[Django] swagger 적용 방법

코딩은 돈이 된다·2024년 7월 2일

api 문서화를 위해서 swagger를 사용하기로 하였고, 미루면 상당히 귀찮아지니까 개발 초기에 설정을 전부 진행하였다.

먼저 설치해야할 것

pip install djangorestframework
pip install drf-yasg

settings.py

INSTALLED_APPS = [
    ...
    "rest_framework",
    "drf_yasg",
    ...
]

setting.py는 뭐 없다. 그냥 이거 두 개 넣어주면 끝이다.

url.py

schema_view = get_schema_view(
    openapi.Info(
        title="프로젝트 이름",
        default_version='프로젝트 버전',
        description="프로젝트 설명",
        terms_of_service="https://www.google.com/policies/terms/",
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
)

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-v1",
    ),
    ...
]

title과 같은 것들을 본인이 사용하는 프로젝트에 맞게 바꿔주면 된다.
(안바꿔도 사실 영향 없음)

사용법

이후엔 django 프로젝트를 실행하고 해당 주소에 접속하면 된다.
만약 주소가 localhost:8000/이라면
뒤에 swagger를 추가하면 swagger 페이지로 이동할 수 있다.
로컬호스트로 테스트


나는 login과 logout에 대해서 swagger를 적용해놨기 때문에 뜨지만, 처음 접속한다면 아무것도 안뜰 것이다.(ViewSet 사용자 제외)

어떻게 쓰는가?

LogoutView

class LogoutView(APIView):
    @swagger_auto_schema(operation_id="사용자 로그아웃")
    def post(self, request):
        try:
            refresh_token = request.data['refresh']
            if refresh_token is None:
                return Response("리프레시 토큰이 필요합니다.", status=400)

            token = RefreshToken(refresh_token)
            token.blacklist()

            return Response("로그아웃되었습니다.", status=205)
        except Exception as e:
            return Response({"detail": "로그아웃에 실패했습니다.", "error": str(e)}, status=400)

LogoutView의 예시 코드이다.
여기 보면 @swagger_auto_schema라는 것을 통해 기본적으로 swagger에서 보여지는 형태를 설정해준다.
사실 이게 전부이다.
사용하는 방법은 operation_id를 넣어주면 되는데, 이건 아까 사진에서 본 것처럼 api에 대한 설명이 된다.

다음 예시를 보자

LoginView

class LoginView(APIView):
    @swagger_auto_schema(
        operation_id="사용자 로그인",
        request_body=LoginSerializer
    )
    def post(self, request):
        try:
            data = JSONParser().parse(request)
            serializer = LoginSerializer(data=data)
            if serializer.is_valid(raise_exception=True):
                user = serializer.validated_data['user']
                refresh = RefreshToken.for_user(user)

                return Response({
                    'refresh': str(refresh),
                    'access': str(refresh.access_token),
                }, status=200)
        except Exception as e:
            return Response("로그인에 실패했습니다.", status=400)

LoginView의 예시코드이다.
여기선 달라진 점이 있는데 request_body가 추가됐다는 점이다.
왜 필요할까?

logout get 요청의 경우에는 request_body가 없어도 가능하지만,
login post 요청의 경우에는 request_body가 있어야 한다.(사용자 아이디, 비밀번호)

그래서 serializer를 request_body로 설정해주면 된다.

물론 api 테스트를 진행할 때에는 ex) Postman
swagger request_body설정을 해주지 않더라도 잘 동작한다.
(그냥 swagger에서 보이는 형태를 제공하는 코드이기 때문)
하지만, swagger에서 api테스트를 진행하려면 꼭 작성해줘야 한다.

Swagger를 적용하기로 하였다면, 코드를 push하기 전에 swagger에 들어가서 정상적으로 입력이 되었는지를 확인하자!

0개의 댓글