왜 DRF를 사용해야할까? Django REST Framework(DRF)는 RESTful API 개발을 위해 django 위에 추가된 라이브러리로 RESTful API 개발을 위해 필요한 공수를 줄여준다. API를 개발할 때 필요한 authentication, permission, throttling 등을 쉽게 구현할 수 있도록 해주는데 아래에 DRF에서 정의하는 settings만 봐도 API 개발에 필요한 것들을 쉽게 추가할 수 있음을 알 수 있다.
DEFAULTS = { # Base API policies 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ], 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ], 'DEFAULT_THROTTLE_CLASSES': [], 'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation', 'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata', 'DEFAULT_VERSIONING_CLASS': None, # Generic view behavior 'DEFAULT_PAGINATION_CLASS': None, 'DEFAULT_FILTER_BACKENDS': [], # Schema 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.openapi.AutoSchema', # Throttling 'DEFAULT_THROTTLE_RATES': { 'user': None, 'anon': None, }, 'NUM_PROXIES': None, # Pagination 'PAGE_SIZE': None, # Filtering 'SEARCH_PARAM': 'search', 'ORDERING_PARAM': 'ordering', # Versioning 'DEFAULT_VERSION': None, 'ALLOWED_VERSIONS': None, 'VERSION_PARAM': 'version', # Authentication 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, # View configuration 'VIEW_NAME_FUNCTION': 'rest_framework.views.get_view_name', 'VIEW_DESCRIPTION_FUNCTION': 'rest_framework.views.get_view_description', # Exception handling 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', 'NON_FIELD_ERRORS_KEY': 'non_field_errors', # Testing 'TEST_REQUEST_RENDERER_CLASSES': [ 'rest_framework.renderers.MultiPartRenderer', 'rest_framework.renderers.JSONRenderer' ], 'TEST_REQUEST_DEFAULT_FORMAT': 'multipart', # Hyperlink settings 'URL_FORMAT_OVERRIDE': 'format', 'FORMAT_SUFFIX_KWARG': 'format', 'URL_FIELD_NAME': 'url', # Input and output formats 'DATE_FORMAT': ISO_8601, 'DATE_INPUT_FORMATS': [ISO_8601], 'DATETIME_FORMAT': ISO_8601, 'DATETIME_INPUT_FORMATS': [ISO_8601], 'TIME_FORMAT': ISO_8601, 'TIME_INPUT_FORMATS': [ISO_8601], # Encoding 'UNICODE_JSON': True, 'COMPACT_JSON': True, 'STRICT_JSON': True, 'COERCE_DECIMAL_TO_STRING': True, 'UPLOADED_FILES_USE_URL': True, # Browsable API 'HTML_SELECT_CUTOFF': 1000, 'HTML_SELECT_CUTOFF_TEXT': "More than {count} items...", # Schemas 'SCHEMA_COERCE_PATH_PK': True, 'SCHEMA_COERCE_METHOD_NAMES': { 'retrieve': 'read', 'destroy': 'delete' }, } Serializer 클래스로 DB 인스턴스를 python native 데이터 타입으로 변환할 수 있고 그 반대의 과정도 쉽게 구현할 수 있다. 그리고 다양한 추상화 단계에서 API를 개발할 수 있도록 돕는데, 뷰를 예를들면 APIView, GenericAPIView, GenericViewSet 으로 갈수록 추상화 단계가 높아지고 customization의 정도에 따라 필요한 클래스를 상속받아 API를 구현할 수 있다. 특히 viewset과 router를 통해 코드 몇줄로 CRUD를 구현할 수 있어 코드의 중복을 줄일 수 있는데 실제로 아래 예시는 DRF 공식문서 튜토리얼 > Quickstart 의 코드로 viewset과 router 의 조합으로 API를 작성했다. 먼저 serializer를 구현하여 Viewset의 serializer_class에 할당하고, DefaultRouter에 viewset을 등록하여 urlconf를 생성할 수 있다. 그리고 Django에서 기본적으로 제공하는 HttpRequest, HttpResponse 클래스를 확장하여 API 요청을 처리하는데 필요한 기능을 추가로 제공한 Request, Response 클래스를 사용하는데 실제로 Request 클래스를 초기화할 때 parsers, authenticators, negotiator 인자 등을 추가로 받을 수 있다
...