ABOUT ME

궁금하니깐

Today
Yesterday
Total
  • [Django REST framework] 튜토리얼 2 : 요청 및 응답
    코딩/🟢 DJANGO 2022. 2. 26. 00:14

    우리는 REST 프레임워크의 핵심을 다루기 시작할 것입니다. 몇 가지 필수 구성 요소를 소개하겠습니다.

    Request objects 요청 객체

    REST 프레임 워크에서 Request는 regular를 확장하는 객체를 도입하고 

    HttpResponse보다 유연한 요청 구문 parsing(분석)을 제공한다.

    Request객체 의 핵심 기능 request.data은 와  request.POST 유사하지만 Web API 작업에 더 유용한 속성입니다.

     

    request.POST  # Only handles form data.  Only works for 'POST' method.
    
    ⬇️
    """
    Handles arbitrary data.  Works for 'POST', 'PUT' and 'PATCH' methods.
    """
    request.data

    Response objects 응답 객체

    Rest Framework는 Response 객체를 가지고 있다. 

    이 객체는 TemplateResponse 유형이며, 렌더링 되지않은 컨텐츠를 가져오고,

    컨텐츠 유통을 통해 클라이언트에게 반환활 올바른 컨텐츠 형식을 결정한다.

    return Response(data)  # 클라이언트가 요청한 컨텐츠유형으로 렌더링함

    Status codes 상태코드

    보기에서 숫자 HTTP 상태 코드를 사용하는 것이 항상 명확하게 읽을 수 있는 것은 아니다.

    오류 코드가 잘못된 경우 알아차리지 않기 쉽습니다. 

    REST 프레임워크는 모듈에서 HTTP_400_BAD_REQUEST 와 같이 각 상태 코드에 대해 보다 명확한 식별자를 제공 합니다. 

    status숫자 식별자를 사용하는 것보다 전체적으로 사용하는 것이 좋습니다.

    Wrapping API View 

    REST framework는 2가지 wrapper를 제공한다. 

    1. @api_view decorator for working with 함수 기반 뷰에서 동작한다. 

    2. APIView class for working with 클래스기반 뷰에서 동작한다,. 

     

    Pulling it all together

    자, 이제 새로운 컴포넌트를 이용해서 이전에 만들었던 view를 리팩토링을 할 것이다. 

    1. 함수기반뷰 작성 by  @api_view

    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, or 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)

    instance view는 이전 예제에 비해 향상되었다. 

    또한 네이밍된 status code를 사용하고 그것은 명백한 reponse의 의미를 전달할 수 있다. 

     

    이제 개별 snippet을 위한 뷰를 수정해보자. 

    @api_view(['GET', 'PUT', 'DELETE'])
    def snippet_detail(request, pk):
        """
        Retrieve, update or delete a code snippet.
        """
        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(snippet, 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)

    예전에 했던 일반적인 Django views와 다르지 않다. 

    중요한것은 더이상 우리의 요청과 응답을 정확히 명시안해도 된다는 것이다. 

    request.data 는 json 요청도 처리할 수 있고, 다른 형식의 데이터를 받을 수 있기 때문이다. 

    또한 앞서말한것과 같이 response 객체를 반환하지만 REST framework가 response를 올바른 컨텐츠유형으로 렌더링하도록 허용한다. 

     

    Adding  optional format suffiixes to our URLs

    response가 더이상 하나의 컨텐츠 유형에 고정되지 않는다는 것을 활용해보자.

    API endpoint에 suffixes(접미사) 에 대한 지원을 추가할 것이다. 

    format suffix를 사용하면 지정된 형식을 명시적으로 참조하는 URL이 제공되며, 

    API가 http://example.com/api/items/4.json. 같은 URL을 처리할 수있다. 

     

    1) 양쪽 view에 아래처럼 format 키워드를 추가해보자. 

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

    2) format_suffix_patterns를 url에 적용하기 위해 url.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),
    ]
    
    """
    url패턴을 format_suffix_pattern을 따르도록 설정
    """
    urlpatterns = format_suffix_patterns(urlpatterns)

    이러한 추가 URL 패턴을 반드시 추가할 필요는 없지만,

    특정형식을 참조하는 간단하고 깔끔한 방법을 제공하는 것이다. 

     

    How's it looking?

    모든 것이 거의 비슷하게 동작하지만, 유효하지 않은 요청에 대해서 더 좋은 오류처리를 해준다. 

    이전과 마찬가지로 모든 스니펫 목록을 얻을 수 있다. 

    http http://127.0.0.1:8000/snippets/
    
    HTTP/1.1 200 OK
    ...
    [
      {
        "id": 1,
        "title": "",
        "code": "foo = \"bar\"\n",
        "linenos": false,
        "language": "python",
        "style": "friendly"
      },
      {
        "id": 2,
        "title": "",
        "code": "print(\"hello, world\")\n",
        "linenos": false,
        "language": "python",
        "style": "friendly"
      }
    ]

    우리는 Accept 헤더를 사용하여 response 되는 형식을 제어할 수 있다.

    http http://127.0.0.1:8000/snippets/ Accept:application/json  # Request JSON
    http http://127.0.0.1:8000/snippets/ Accept:text/html         # Request HTML

    또는 format suffix를 추가해서 제어할 수 있다. 

    http http://127.0.0.1:8000/snippets.json  # JSON suffix
    http http://127.0.0.1:8000/snippets.api   # Browsable API suffix
    

    마찬가지로 Content-Type 헤더를 사용하여 우리가 보낸 request의 형식을 컨트롤 할 수 있다. 

    # POST using form data
    http --form POST http://127.0.0.1:8000/snippets/ code="print(123)"
    
    {
      "id": 3,
      "title": "",
      "code": "print(123)",
      "linenos": false,
      "language": "python",
      "style": "friendly"
    }
    
    # POST using JSON
    http --json POST http://127.0.0.1:8000/snippets/ code="print(456)"
    
    {
        "id": 4,
        "title": "",
        "code": "print(456)",
        "linenos": false,
        "language": "python",
        "style": "friendly"
    }​

    만약에 http request에 --debug 스위치를 추가하면 request 헤더에서 요청한 타입을 볼 수 있다 . 

     

    Browsablity 검색할 수 있는

    API 는 클라이언트 요청에 따라 response 유형을 선택한다.

    이에 따라 기본적으로 웹 브라우저에서 해당 리소스를 요청할때 리소스의 HTML형식 표현을 반환해준다.

    이를 통해 API가 완벽하게 web-browsable API가 있으면 유용성이 크게 향상되고, API를 쉽게 개발하고 사용할 수 있다

    또한, API를 검샇고 사용하려는 다른 개발자의 진입장벽을 크게 낮출 수 있다. 

    browsable Api 특징 또는 어떻게 커스텀 마이징 하는 정보에 대한 것은  browsable api 를 참고하자. 

Designed by Tistory.