Swagger?
- 어플리케이션의 REST API 문서를 자동으로 구성하는 도구입니다.
지금까지는 API의 명세를 주로 Notion에 작성하며 활용했지만 API별로 문서화한다는게 생각보다 시간도 많이 소모되고, 실수로 인해 오타가 나거나 빼먹는 일도 있기 때문에 앞으로의 프로젝트에서 이러한 점을 개선시켜보고자 Swagger를 적용해보도록 하겠습니다.
drf-yasg
를 사용했습니다.django rest framework
도 함께 설치하는 것이 필수 입니다. pip install djangorestframework
pip install drf-yasg
INSTALLED APPS = [
...
'drf-yasg',
'rest_framework'
...
]
project/urls.py
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
...
schema_view = get_schema_view(
openapi.Info(
title="Swagger_Practise API",
default_version='v1',
description="Swagger Test를 위한 유저 API 문서",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@snippets.local"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
...
# 디버그일때만 swagger 문서가 보이도록 해주는 설정,
# 여기에 urlpath도 작성 가능해서 debug일때만 작동시킬 api도 설정할 수 있음
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'),
]
python manage.py runseerver
실행 후, /swagger
로 접속views.py
class SWAGGERTESTAPIView(APIVIEW):
permission_classes = [permissions.AllowAny] #swagger에서 해당 API에 접근할 수 있는 권한 설정 (AllowAny - 모두)
@swagger_auto_schema(
operation_description="API 설명",
operation_summary="API의 간단한 타이틀, 통합하는 주제",
operation_id='API 구분하는 고유 값 (중복의 가능성있기 때문에 신경써야함)',
tags=['그룹핑화 할 수 있는 곳'],
manual_parameters=[Authorization], #query_params, request_header를 작성하는 부분
query_serializer=ManagementUserSerializer, #query_params, request_header 작성(Serializer로 자동 포맷할 경우)
responses={ #request_body도 responses와 같은 방법으로 작성, Mock-up 형태
)
def post(self, request):
...
serializer.py
from rest_framework import serializers
...
# request_body
class LoginUserSerializer(serializers.Serializer):
username = serializers.CharField(help_text="아이디")
password = serializers.CharField(help_text="패스워드")
class UserUpdateSerializer(serializers.Serializer):
password = serializers.CharField(help_text="패스워드")
nickname = serializers.CharField(help_text="닉네임")
profile = serializers.ImageField(help_text="프로필이미지")
views.py
에서 작성한 Serializer를 import해준 후 적용
# 로그인 API - jwt인증방식의 로그인 api
class LoginAPIView(APIView):
permission_classes = [permissions.AllowAny]
@swagger_auto_schema(
tags=["로그인"],
request_body=LoginUserSerializer, # serializer 자동 포맷한 경우
responses = { # 직접한 경우
201: openapi.Response( # status code별로 구분해서 적용가능
description="201 OK",
schema=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties = {
'access_token': openapi.Schema(type=openapi.TYPE_STRING, description="access_token"),
'access_exp': openapi.Schema(type=openapi.TYPE_STRING, description="access_exp"),
'refresh_token': openapi.Schema(type=openapi.TYPE_STRING, description="refresh_token"),
}
)
),
400: 'KeyNotFound',
500: 'Server Error'
}
)
def post(self, request):
/swagger
접속 후, 확인drf-yasg
가 적용되지 않았다는 문제 발생
drf-yasg
설치 후, 환경 설정을 제대로 해주었고 pip install -U drf-yasg
로 업데이트
- 익숙해지기만 하면 API명세를 작성하는 시간도 많이 줄어들고, 프론트엔드와 협업하는 과정에서 매우 유용할 것임을 체감했습니다.
views.py
에 @swagger_auto_schema()를 직접 작성했을 경우, 코드가 복잡해져서 가독성이 떨어지는 것 같습니다.- 현재 Swagger 자체 API 테스트 과정에서 jwt를 header에 넣지 않고 endpoint만 입력하더라도 status code 200과 함께 테스트가 통과되는 문제가 발생했습니다.
(토큰이 없을 경우 unauthenticated 반환이 정상 : API 자체 로직의 문제인지, swagger 적용을 잘못한 것인지 검토 필요)- 전체 코드는 https://github.com/wodnrP/Swagger_practise 에 올려두었습니다.