본문 바로가기
Django

DRF Tutorial 5 Relationships & Hyperlinked APIs

by AlbertIm 2024. 9. 14.

시작

이번 포스트에서는 DRF(Django Rest Framework) 튜토리얼을 따라 RelationshipsHyperlinked APIs을 다루는 방법을 알아보겠습니다. 본 포스트는 macOSVS Code 환경에서 진행됩니다.

본문

루트 API Endpoint 생성

API에서 각 엔드포인트를 명확하게 탐색할 수 있도록 루트 엔드포인트를 만들겠습니다.

snippets/views.pyapi_root 뷰를 추가하여 모든 API의 시작점을 정의합니다.

# ...
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse

@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'snippets': reverse('snippet-list', request=request, format=format)
    })

# ...

 

이제 snippets/urls.py에 API 루트 경로를 추가합니다.

urlpatterns = [
    # ...
    path("", views.api_root),
]

 

이로써 루트 URL에서 userssnippets 엔드포인트로 쉽게 접근할 수 있습니다.

Highlighted snippets Endpoint 생성

snippets의 하이라이트 된 버전을 반환하는 엔드포인트를 추가합니다.

이를 위해 SnippetHighlight 뷰를 생성합니다.

from rest_framework import renderers

class SnippetHighlight(generics.GenericAPIView):
    queryset = Snippet.objects.all()
    renderer_classes = [renderers.StaticHTMLRenderer]

    def get(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

 

 

snippets/urls.pySnippetHighlight 뷰를 위한 URL 패턴을 추가합니다.

urlpatterns = [
    # ...
    path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view()),
]

이제 특정 스니펫의 하이라이트 된 코드를 가져올 수 있습니다.

Hyperlinking API

DRF에서는 Hyperlinked API를 지원하여 모델 간의 관계를 보다 직관적으로 표현할 수 있습니다. 이를 위해 HyperlinkedModelSerializer를 사용합니다.

HyperlinkedModelSerializerModelSerializer과 다른 점은:

  • 기본적으로 id 필드는 포함되지 않습니다.
  • HyperlinkedIdentityField를 사용하는 URL 필드가 포함됩니다.
  • PrimaryKeyRelatedField 대신 HyperlinkedRelatedField를 사용하여 관계를 표현합니다.

snippets/serializers.py에서 SnippetSerializerUserSerializer를 수정합니다.

class SnippetSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')
    highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')

    class Meta:
        model = Snippet
        fields = ['url', 'id', 'highlight', 'owner',
                  'title', 'code', 'linenos', 'language', 'style']


class UserSerializer(serializers.HyperlinkedModelSerializer):
    snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)

    class Meta:
        model = User
        fields = ['url', 'id', 'username', 'snippets']

이렇게 하면 UserSerializerSnippetSerializer에서 각각 url 필드가 자동으로 추가되어 하이퍼링크 형태로 데이터를 표현할 수 있습니다.

URL 패턴을 수정

HyperlinkedModelSerializer에서 사용하는 URL 패턴을 반영하기 위해 snippets/urls.py를 업데이트합니다.

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

# API endpoints
urlpatterns = format_suffix_patterns([
    path('', views.api_root),
    path('snippets/', views.SnippetList.as_view(), name='snippet-list'),
    path('snippets/<int:pk>/', views.SnippetDetail.as_view(),
        name='snippet-detail'),
    path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view(),
        name='snippet-highlight'),
    path('users/', views.UserList.as_view(),
        name='user-list'),
    path('users/<int:pk>/', views.UserDetail.as_view(),
        name='user-detail')
])

이로써 DRF의 기본 엔드포인트가 모두 하이퍼링크 형태로 제공됩니다.

 

Pagination를 추가

DRF에서 간단하게 페이지네이션을 추가할 수 있습니다.

config/settings.py 파일을 수정하여 페이지네이션 설정을 추가합니다.

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

 

이제 각 API의 응답에서 페이지네이션을 적용하여 한 페이지에 10개의 항목만 표시되도록 설정되었습니다.

마무리

이번 포스트에서는 Django Rest Framework를 사용하여 하이퍼링크 방식의 API를 구현하고 페이지네이션을 추가하는 방법을 살펴보았습니다. 이를 통해 Django 프로젝트에서 관계형 API를 보다 직관적이고 쉽게 구성할 수 있습니다. DRF에서 제공하는 기능들을 사용하여 효율적인 API 설계를 이어나갈 수도 있습니다.

 

참고자료

'Django' 카테고리의 다른 글

STATICFILES_DIR vs STATIC_ROOT  (0) 2024.10.21
DRF Tutorial 6 ViewSets & Routers  (0) 2024.09.14
DRF Tutorial 4 Authentication & Permissions  (1) 2024.09.14
DRF Tutorial 3 Class-based Views  (0) 2024.09.14
DRF Tutorial 2 Requests and Responses  (0) 2024.09.11

댓글