Django

[django/drf]Djang Rest Framwork 공식문서 튜토리얼2 (Requests and responses)

a-몬드 2022. 7. 12. 10:29
반응형

request와 response, status를 보내는 것이 아닌, rest_framework에서 지원하는 방식으로 status를 보낸다. 

응답의 의미를 명확하게 전달할 수 있다는 장점이 있다.

 

REST프레임 워크의 필수 구성 요소들

 

✅Request object

Request object의 핵심 기능은 request.POST와 비슷한 request.data 속성이다. 

Web API에서 훨씬 더 유용하다.

request.POST # form data(html의 form)에서만 다룰 수 있다. 그리고 POST 메소드에서만 작동한다. 
request.data   # 임의 데이터를 다룰 수 있다. POST, PUT, PATCH 메소드에서 작동한다.

 

✅Response object

Response object는 TemplateResponse 유형의 렌더링 되지 않은 콘텐츠를 가져오고 content negotiation(협상)을 하여 클라이언트에 반환할 올바른 content type을 결정한다. 

return Response(data) # 클라이언트의 요청에 따라 content type으로 렌더링한다.

 

✅Status codes

REST framework는 모듈 HTTP_400_BAD_REQUEST처럼 각 status code에 대해 명확한 식별자를 제공한다. 

숫자 status code를 사용하는 것 보다 좋다.

 

✅ wrapping views API 

REST framework는 API views를 만들 때 너는 사용할 수 있는 두 가지 wrapper를 제공한다. 

1. @api_view  함수 기반 views로 작업할 수 있다.

2.  APIView  클래스 기반 views로 작업할 수 있다. 

 

wrapper는 405 method not allowed에 해당하는 경우 reponse를 반환하고 잘못된 형식의 입력으로 request.data에 액세스 할 때 발생한느 ParseError예외를 처리하는 등의 기능을 제공한다.

 

 

1. 튜토리얼 1의 views @api_view로 refactor하기

 

전체 목록 조회, snippet 추가 veiw 함수 리팩토링

#Snippets/views.py
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'])# 함수기반의 api_view wrapper사용하기
def snippet_list(request):
    if request.method == 'GET': # snippet 목록 조회 메소드
        snippets = Snippet.objects.all() # 목록  DB에서 가져오기
        serializer = SnippetSerializer(snippets, many=True) # serializer, json으로 변환하기
        return Response(serializer.data)

    elif request.method == 'POST': # snippet 추가 메소드
        serializer = SnippetSerializer(data=request.data)# 받은 json 데이터 Snippet 변환하기
        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)

snippet 조회, 변경, 삭제 view 함수 리팩토링

@api_view(['GET','PUT','DELETE'])
def snippet_detail(request, pk):
    # 현재 존재하는 snippet인지 확인
    try:
        snippet = Snippet.objects.get(pk=pk) # 요청한 snippet이 유효한 snippet인지 확인
    except Snippet.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)
    # GET 메소드로 요청시 요청 snippet 데이터 보내줌
    if request.method == 'GET':
        serializer = SnippetSerializer(snippet)
        return Response(serializer.data)
    # PUT 메소드로 요청 시 해당 pk snippet을 data로 변경
    elif request.method == 'PUT':
        serializer = SnippetSerializer(snippet, data=request.data) # json데이터 serializer하기
        if serializer.is_valid():# 변경할 데이터가 유효하면
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    # DELETE 메소드로 요청시 해당 pk snippet 삭제
    elif request.method == 'DELETE':
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

 

URL에 suffixes 추가  

response가 더 이상 하나의 contet 유형에 hardwired 연결되어 있지 않다는 점을 활용하려면 API end point에 format suffixes를 추가

format suffixes를 사용하면 지정된 형식을 명시적으로  참조하는 URL이 제공된다.

views.py의 함수에 아래처럼 format suffixed를 추가해준다. 

def snippet_list(request, format=None):
def snippet_detail(request, pk, format=None):

 

urls.py파일에 기존 URL에 format_suffix_patterns를 추가해준다.

#snippets/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),
]

#format_suffix_patterns 추가하기
urlpatterns = format_suffix_patterns(urlpatterns)

 

 

추가 URL 패턴을 반드시 추가할 필요는 없지만 특정 형식을 참조할 수 있는 단순하고 깔끔한 방법을 제공한다.

 

💚결과 확인

python manage.py runserver 하여 브라우저에 http://127.0.0.1:8000/snippets/ 들어가면 아래 화면이 보인다. 

 

 Accept  header를 사용하여 반환되는 응답 형식을 제어할 수 있다.

1,2는 POSTMAN으로 테스트

3,4는 format suffixes를 추가하였으니 suffixes로 테스트

 

1. Accept : application/json

2. Accept : text/html

 

3. json suffix

http://127.0.0.1:8000/snippets.json

4. api suffix

 

✅ content-type header POST 테스트

1. form data로 POST

2. json으로 POST 

 

참조

https://www.django-rest-framework.org/tutorial/2-requests-and-responses/

반응형