[DRF] 공식 문서 - Metadata 정리
1. Metadata
- REST 프레임워크는 OPTIONS 요청에 대해 API가 어떻게 응답해야 하는지 결정하는 구성 가능한 메커니즘을 포함하고 있습니다. 이를 통해 API 스키마나 다른 리소스 정보를 반환할 수 있다.
- 현재 HTTP OPTIONS 요청에 대해 반환되어야 하는 응답 스타일에 대해 널리 통용되는 규칙은 없습니다. 따라서 우리는 유용한 정보를 반환하는 임시 방식의 응답을 제공한다.
- 다음은 기본적으로 반환되는 정보를 보여주는 예시 응답이다.
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
{
"name": "To Do List",
"description": "List existing 'To Do' items, or create a new item.",
"renders": [
"application/json",
"text/html"
],
"parses": [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"
],
"actions": {
"POST": {
"note": {
"type": "string",
"required": false,
"read_only": false,
"label": "title",
"max_length": 100
}
}
}
}
1) 메타데이터 체계 설정(Setting the metadata scheme)
- 'DEFAULT_METADATA_CLASS' 설정 키를 사용하여 메타데이터 클래스를 전역적으로 설정할 수 있다.
REST_FRAMEWORK = {
'DEFAULT_METADATA_CLASS': 'rest_framework.metadata.SimpleMetadata'
}
- 또는 뷰마다 개별적으로 메타데이터 클래스를 설정할 수도 있다.
class APIRoot(APIView):
metadata_class = APIRootMetadata
def get(self, request, format=None):
return Response({
...
})
- REST 프레임워크 패키지에는 SimpleMetadata라는 하나의 메타데이터 클래스 구현체만 포함되어 있다. 다른 스타일을 사용하려면 사용자 정의 메타데이터 클래스를 구현해야 한다.
2) 스키마 엔드포인트 생성(Creating schema endpoints)
- 일반적인 GET 요청으로 액세스되는 스키마 엔드포인트를 생성하는 특정 요구 사항이 있다면, 메타데이터 API를 재사용하는 것을 고려할 수 있다.
- 예를 들어, 다음과 같은 추가적인 route를 뷰셋에 사용하여 링크 가능한 스키마 엔드포인트를 제공할 수 있다.
@action(methods=['GET'], detail=False)
def api_schema(self, request):
meta = self.metadata_class()
data = meta.determine_metadata(request, self)
return Response(data)
- 이러한 접근 방식을 선택하는 이유는 여러 가지가 있을 수 있다. 그 중 하나는 OPTIONS 응답이 캐시할 수 없다는 점이다.
- are not cacheable : https://www.mnot.net/blog/2012/10/29/NO_OPTIONS
2. 사용자 정의 메타데이터 클래스(Custom metadata classes)
- 사용자 정의 메타데이터 클래스를 제공하려면 BaseMetadata를 재정의하고 determine_metadata(self, request, view) 메서드를 구현해야 한다.
- 반환할 수 있는 유용한 정보로는 JSON 스키마와 같은 형식으로 스키마 정보를 반환하거나, 디버그 정보를 관리자 사용자에게 반환하는 등의 작업이 있을 수 있다.
- JSON schema : https://json-schema.org/
1) Example
- 다음 클래스는 OPTIONS 요청에 반환되는 정보를 제한하는 데 사용할 수 있다.
class MinimalMetadata(BaseMetadata):
"""
Don't include field and other information for `OPTIONS` requests.
Just return the name and description.
"""
def determine_metadata(self, request, view):
return {
'name': view.get_view_name(),
'description': view.get_view_description()
}
- 그런 다음 설정을 구성하여 이 사용자 정의 클래스를 사용하면 된다.
REST_FRAMEWORK = {
'DEFAULT_METADATA_CLASS': 'myproject.apps.core.MinimalMetadata'
}
3. Third party packages
1) DRF-schema-adapter
- drf-schema-adapter는 프런트엔드 프레임워크와 라이브러리에 스키마 정보를 제공하기 쉽게하는 도구 세트이다. 메타데이터 mixin과 2개의 메타데이터 클래스, 여러 개의 어댑터를 제공하여 json-schema 및 다양한 라이브러리에서 읽을 수 있는 스키마 정보를 생성하는 데 적합하다.
- 또한 특정 프런트엔드와 함께 작업하기 위해 직접 어댑터를 작성할 수도 있다. 이 경우 해당 스키마 정보를 json 파일로 내보내는 내보내기 도구도 제공된다.
- drf-schema-adapter : https://github.com/drf-forms/drf-schema-adapter
- json-schema : https://json-schema.org/
- 예시
from rest_framework.views import APIView
from rest_framework.response import Response
from drf_schema_adapter.metadata import SchemaMetadataMixin
from drf_schema_adapter.metadata import JsonSchemaMetadataClass
class MyAPIView(SchemaMetadataMixin, APIView):
"""
MyAPIView는 스키마 메타데이터를 제공하는 APIView입니다.
"""
metadata_class = JsonSchemaMetadataClass
"""
metadata_class는 JsonSchemaMetadataClass를 사용하여 JSON 스키마 메타데이터를 생성합니다.
"""
def get(self, request):
"""
GET 요청을 처리하는 메소드입니다.
"""
data = {
'message': 'Hello, world!',
'count': 10,
'results': ['item1', 'item2', 'item3']
}
return Response(data)
def post(self, request):
"""
POST 요청을 처리하는 메소드입니다.
"""
# Request body 스키마 정보를 생성합니다.
request_schema = {
'type': 'object',
'properties': {
'name': {'type': 'string'},
'age': {'type': 'integer'}
},
'required': ['name']
}
# Response body 스키마 정보를 생성합니다.
response_schema = {
'type': 'object',
'properties': {
'message': {'type': 'string'}
}
}
# 스키마 정보를 메타데이터에 등록합니다.
self.set_request_body_schema(request, request_schema)
self.set_response_body_schema(response_schema)
# 요청 처리 로직을 구현합니다.
name = request.data.get('name')
age = request.data.get('age')
message = f"Hello, {name}! You are {age} years old."
data = {
'message': message
}
return Response(data)
- 위의 코드는 DRF-schema-adapter를 사용하여 스키마 정보를 제공하는 예시이다. MyAPIView 클래스는 APIView를 상속하고, SchemaMetadataMixin을 사용하여 스키마 메타데이터를 제공한다. metadata_class 속성을 설정하여 JSON 스키마 메타데이터를 생성하는 JsonSchemaMetadataClass를 사용한다.
- GET 요청을 처리하는 get 메소드와 POST 요청을 처리하는 post 메소드가 구현되어 있다. POST 요청의 경우, Request body와 Response body의 스키마 정보를 생성하고, set_request_body_schema와 set_response_body_schema 메소드를 사용하여 메타데이터에 등록한다. 이후 요청 데이터를 처리하고 응답을 반환한다.
- 이와 같이 DRF-schema-adapter를 사용하면 프론트엔드 프레임워크 및 라이브러리에 스키마 정보를 제공할 수 있다. 필요에 따라 특정 프론트엔드와 함께 작동하기 위해 사용자 정의 어댑터를 작성하거나, 스키마 정보를 JSON 파일로 내보내는 기능을 활용할 수도 있다.
- 공식 사이트 문서 : https://www.django-rest-framework.org/api-guide/metadata/