Swagger

GreenBean·2022년 4월 12일
0
post-thumbnail

Swagger

Swagger란?

  • API 문서화 도구
  • REST API를 설계•빌드•문서화 및 사용하는 데 도움이 되는 OpenAPI 사양을 중심으로 구축 된 오픈 소스 도구 세트

Swagger 사용 이유

  • 적용하기 쉬움
    • 코드 몇 줄만 추가하면 만들 수 있음
  • 테스트 할 수 있는 UI를 제공
    • 문서 화면에서 API를 바로 테스트 가능

Swagger 적용 방법

  • drf-yasg 사용

drf-yasg 설치

pip install drf-yasg

settings.py

# 예시 코드
INSTALL_APPS = [
	...
    'drf_yasg',
    ...
]

urls. py

# 예시 코드
from django.conf import settings
from django.urls import (
    path,
    include,
    re_path,
)

from rest_framework import permissions

from drf_yasg import openapi
from drf_yasg.views import get_schema_view

...

# swagger 정보 설정, 관련 엔드포인트 추가
schema_view = get_schema_view(
    openapi.Info(
        title='Hwaya API',
        default_version='v1',
        description='Description',
        contact=openapi.Contact(email='contact@snippets.local.txt'),
        license=openapi.License(name='BSD License'),
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
)

# swagger 엔드포인트는 DEBUG Mode에서만 노출
if settings.DEBUG: 
    urlpatterns += [ 
        re_path(
            r'^swagger(?P<format>\.json|\.yaml)$', 
            schema_view.without_ui(cache_timeout=0), 
            name='schema-json'
        ), 
        re_path(
            r'^swagger/$', 
            schema_view.with_ui('swagger', cache_timeout=0), 
            name='schema-swagger-ui'
        ), 
        re_path(
            r'^redoc/$', 
            schema_view.with_ui('redoc', cache_timeout=0), 
            name='schema-redoc'
        ) 
    ]
  • 공식 문서에 따르면 다음과 같이 총 4개의 엔드포인트가 생성
    • /swagger.json
      • a JSON view of your API specification
    • /swagger.yaml
      • a YAML view of your API specification
    • /swagger/
      • swagger-ui view of your API specification
    • /redoc/
      • a ReDoc view of your API specification
  • 세팅을 마치고 나면 프로젝트-주소/swagger로 접속했을 때 확인 가능
  • urlpatterns를 바꿔주면 Swagger의 URL 변경 가능
  • get_schema_view의 파라미터를 재설정하여 기본 Swagger 문서의 내용을 변경할 수 있음
    • 문서에는 사용자가 views.py에 생성해 놓은 API들이 나열됨
    • API에 대한 설명을 덧붙이고 싶거나 수정하고 싶다면 method_decorator를 활용해 커스텀 가능

Swagger 기본 설정

  • 정의한 ViewSetdocstring을 추가하면 swagger 문서에서도 나타남
    • 마크다운 문법을 지원
    • 주의할 점은 ViewSetdocstring을 사용하면, CRUD 모든 엔드포인트의 윗부분에 추가됨
      • 이 윗부분을 일반적으로 summary라고 함
# 예시 코드
class TestModel1ViewSet(viewsets.ModelViewSet): 
    """ 
    Model1의 CRUD 
    --- 
    Hello, World 
    """ 
    queryset = TestModel1.objects.all() 
    serializer_class = TestModel1Serializer 
    ...

Swagger Custom

drf-yasg 공식문서 | Custom schema generation

Query Parameter

  • TestModel1ViewSethello 쿼리 파라미터에 대한 설명을 추가하는 방법
# 예시 코드
from drf_yasg import openapi 
from drf_yasg.utils import swagger_auto_schema 

class TestModel1ViewSet(viewsets.ModelViewSet): 
    """ 
    Model1의 CRUD -
    -- 
    Hello, World 
    """ 
    
    queryset = TestModel1.objects.all() 
    serializer_class = TestModel1Serializer 
    
    # hello 파라미터 정보 설정
    param_hello_hint = openapi.Parameter( 
        'hello', 
        openapi.IN_QUERY, 
        description='this is a description of hello.', 
        type=openapi.TYPE_STRING 
    ) 
    
    # hello 파라미터 manual_parameters로 정보 전달
    @swagger_auto_schema(manual_parameters=[param_hello_hint]) 
    def list(self, request, *args, **kwargs):
        ...
  • 먼저 쿼리 파라미터에 대한 정보를 Parameter 클래스로 생성
    • 파라미터 이름, 어떤 부분에 속하는지 (QUERY, BODY, PATH 등), 파라미터 설명, 어떤 타입인지를 생성자에 제공
  • 그 후 데코레이터를 이용해 manual_parameters에 생성한 파라미터 정보를 넘겨줌

Custom Response

  • TestModel1ViewSet의 응답을 추가하는 방법
    • 기본 설정에서는 코드 200의 페이지네이션된 응답만 명시

# 예시 코드
class TestModel2ViewSet(viewsets.ModelViewSet): 
    """ 
    Model2의 CRUD 
    --- 
    Hello, World 
    """ 
    queryset = TestModel2.objects.all() 
    serializer_class = TestModel2Serializer 
    
    # world 파라미터 정보 설정
    param_world_hint = openapi.Parameter( 
        'world', 
        openapi.IN_QUERY, 
        description='this is a description for world.', 
        type=openapi.TYPE_INTEGER 
    ) 
    
    # custom response schema 설정
    error_field = openapi.Schema( 
        'error', 
        description='this is a error string.', 
        type=openapi.TYPE_STRING 
    ) 
    detail_field = openapi.Schema( 
        'detail', 
        description='this is a detail string.', 
        type=openapi.TYPE_STRING 
    ) 
    code_field = openapi.Schema( 
        'code', 
        description='this is a code number.', 
        type=openapi.TYPE_INTEGER 
    ) 
    
    # custom response schema를 적용한 error response 설정
    error_resp = openapi.Schema( 
        'response', 
        type=openapi.TYPE_OBJECT, 
        properties={ 
            'error': error_field, 
            'detail': detail_field, 
            'code': code_field 
        } 
    ) 
    
    # world 파라미터 manual_parameters로 정보 전달
    # error response 추가
    @swagger_auto_schema( 
        manual_parameters=[param_world_hint], 
        responses={ 
            # can use schema or text 
            400: 'this is a test description.', 
            500: error_resp 
        } 
    ) 
    def list(self, request, *args, **kwargs): 
        ...
  • 필요한 필드(Schema)를 만들고, 이를 적절하게 빌드하는 방식
    • Schema 역시 Parameter 클래스와 비슷한 인자를 가지고 있음
  • 데코레이터의 responses에는 dict type을 받으며, keystatus code, value는 응답과 관련된 정보
    • value에는 일반 Text, Schema, Serializer가 들어갈 수 있음

profile
🌱 Backend-Dev | hwaya2828@gmail.com

0개의 댓글