HttpRequest
를 확장한 Request
가 사용되는데, request 파싱을 쉽게 도와준다. 핵심은 request.data
다.
장고 튜토리얼에서 봤었던 request.POST 보다 request.data를 사용하자.
DRF에서는 Response 객체를 사용한다.
TemplateResponse
의 한 형식으로써 렌더링되지 않은 내용을 가져다가 content negotiaion을 통해 클라이언트에 반환할 올바른 내용 유형을 결정한다.
DRF는 좀 더 명시적인 상태 코드를 제공한다.
예를 들어,HTTP_400_BAD_REQUEST
같이 말이다.
단순히 숫자 정보만 담긴 상태코드를 리턴하는 것보다 더 좋은 방법이다.
DRF는 2개의 wrapper를 제공한다.
FBV(Funtion Based View)에 사용된다.
CBV(Class Based View)
이러한 wrapper가 제공하는 기능은 무엇이 있을까?
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
@api_view(["GET", "POST"])
def snippet_list(request):
"""
- List all code snippets
- Create a new snippet"""
if request.method == "GET":
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)
elif request.method == "POST":
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(["GET", "PUT", "DELETE"])
def snippet_detail(request, pk):
"""
- Retrieve
- Update
- Delete
"""
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = SnippetSerializer(snippet)
return Response(serializer.data)
elif request.method == "PUT":
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
많은 변화가 있다.
data = JSONParser().parse(request)
status.HTTP_204_NO_CONTENT
같은 명시적인 HTTP 상태코드
### views.py
def snippet_list(request, format=None):
def snippet_detail(request, pk, format=None):
### urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = [
path("snippets/", views.snippet_list),
path("snippets/<int:pk>/", views.snippet_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Accept
헤더를 사용하여 다른 형식의 데이터를 받아보자.
pip install httpie
>>> http http://127.0.0.1:8000/snippets.json
HTTP/1.1 200 OK
Allow: GET, OPTIONS, POST
Content-Length: 319
Content-Type: application/json
Cross-Origin-Opener-Policy: same-origin
Date: Thu, 28 Sep 2023 07:13:28 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.10.10
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
[
{
"code": "foo = \"bar\"\n",
"id": 1,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print(\"hello, world\")\n",
"id": 2,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
},
{
"code": "print(\"hello, world\")",
"id": 3,
"language": "python",
"linenos": false,
"style": "friendly",
"title": ""
}
]
http http://127.0.0.1:8000/snippets/ Accept:text/html
이를 통해 DRF는 클라이언트가 요청한 content type에 기반한 응답을 제공해 준다. DRF를 사용해보면 알 수 있듯이, 클라이언트가 웹 브라우저에서 DRF를 사용할 때 HTML 형식의 representation으로 리턴한다.
web-browsable API
는 이점이 많다.
개발을 할 때 API를 디버깅하고 사용하기에도 편하다.