[day-49] DRF, 스웨거

Joohyung Park·2024년 3월 15일
0

[모두연] 오름캠프

목록 보기
79/95
post-thumbnail

전에 잠깐 보았던 DRF 기본 글에 대한 복습 및 스웨거에 대해 정리해 보겠다.

기본 세팅

  • 프로젝트 폴더 생성
  • 사용할 앱 만들기
  • settings.py 정의하기
  • 모델 만들기
  • db연동
  • admin.py 정의
  • 관리자 계정 생성

까지는 여태까지 장고 하면서 봤던 내용이고 이후 과정이 조금 다르다.

DRF 관련 pip 설치

pip install djangorestframework
pip install django-cors-headers
pip install drf-yasg 
pip install drf_spectacular
  • django-cors-headers : 응답에 CORS(교차 출처 리소스 공유) 헤더를 추가하는 장고 앱이다. 이를 통해 다른 출처의 클라이언트 측 코드가 API에 액세스할 수 있다.

  • drf-yasg : 장고 REST 프레임워크 API에 대한 OpenAPI(Swagger) 문서를 생성하는 패키지이다.

  • drf_spectacular : drf-yasg와 같은 패키지이고, 원래는 drf-yasg만 설치해도 같이 설치되었는데 지금은 안되어서 따로 설치해야 한다.

settgings.py 수정사항

INSTALLED_APPS = [
	...,
# django lib app
    "rest_framework",
    "corsheaders",
    'drf_spectacular',
	...,
]
MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",  # 최상단 추가
	...,
]

장고 앱에 CORS 헤더를 활성화하며, 장고 서버가 아닌 다른 출처(도메인)에서 실행되는 클라이언트 측 코드(예: 프론트엔드 애플리케이션)가 애플리케이션에 액세스해야 하는 경우에 필요하다.

# 모든 오리진(도메인)의 요청이 장고 애플리케이션에 액세스할 수 있도록 허용
CORS_ORIGIN_ALLOW_ALL = True
# 쿠키 및 기타 자격 증명을 CORS 요청에 포함할 수 있도록 허용
CORS_ALLOW_CREDENTIALS = True
REST_FRAMEWORK = {
    # YOUR SETTINGS  drf의 schema 클래스를 drf-specacular의 AutoSchema로 교체해줍니다.
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

Django REST Framework에서 사용하는 기본 스키마 클래스를 drf_spectacular 패키지에서 제공하는 AutoSchema 클래스로 대체한다.

urls.py 수정사항

# 프로젝트 앱 > urls.py
from django.contrib import admin
from django.urls import path, include
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'), # API 스키마 제공(yaml파일)
    path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), # 테스트할 수 있는 UI
    path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'), # API 문서화를 위한 UI
]
  • http://domain/api/schema/ - 이 URL은 클라이언트 애플리케이션이나 기타 도구에서 API의 구조와 기능을 이해하는 데 사용할 수 있는 YAML 형식의 OpenAPI 스키마를 반환한다.
  • http://domain/api/schema/swagger-ui/ - 이 URL은 API 엔드포인트를 테스트하고 탐색할 수 있는 대화형 인터페이스를 제공하는 Swagger UI를 표시한다. 테스트해볼 수 있는 URL이다.
  • http://domain/api/schema/redoc/ - 이 URL은 OpenAPI 스키마를 기반으로 하는 API의 대체 문서 인터페이스인 ReDoc UI를 표시한다.

그 다음 직접 만든 앱(여기선 blog)의 urls.py를 이전과 같이 정의하고, views.py를 정의한다. views.py는 serializer.py를 만들지는 않고 임시로 만들어서 실습해보는 예제이다.

views.py 수정사항

# blog > views.py

from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Post


@api_view(["GET"])
def blog_list(request):
    blogs = Post.objects.all()
    serializer = []
    for blog in blogs:
        serializer.append(
            {
                "title": blog.title,
                "content": blog.content,
                "created_at": blog.created_at,
                "updated_at": blog.updated_at,
            }
        )
    return Response(serializer)
  • @api_view(["GET"]) : GET 요청만 허용하는 DRF API 뷰로 표시하는 데코레이터
    최종적으로 API 요청에 대한 응답으로 직렬화된 데이터를 반환한다.

FE 서버

Nginx등을 깊게 배우진 않아 임시로 장고 blog앱 내부에 FE라는 폴더를 만들어 간이로 장고와 FE 2개의 서버를 돌리는 느낌을 내보았다.

# FE 서버 > index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <main id="main-container"></main>
<script>
fetch('http://127.0.0.1:8000/blog/')
.then(response => response.json())
.then(data => {
    const mainContainer = document.getElementById('main-container')
    data.forEach(post => {
        const postElement = document.createElement('div')
        postElement.innerHTML = `
            <h1>${post.title}</h1>
            <p>${post.content}</p>
        `
        mainContainer.appendChild(postElement)
    })
})
</script>
</body>
</html>
  • fetch('http://127.0.0.1:8000/blog/') : DRF API(장고 서버)에 GET 요청(데이터를 요청)을 보낸다.
  • response.json() : API로부터 받은 응답을 파싱. 해당 코드에서 응답은 직렬화된 블로그 포스트 데이터(JSON)이다.
    변환된 JSON 데이터를 순회하며 각 제목과 내용을 사용하여 새로운 div요소를 생성하고 이를 main-container에 추가하는 코드이다.

서버로부터 받은 데이터를 활용해 웹 페이지에 동적으로 정보를 표시하며, 이를 통해 사용자가 페이지를 새로고침하지 않아도 최신 데이터를 볼 수 있다.

GET, POST 테스트

썬더 클라이언트라는 vscode 익스텐션으로 테스트 하는 작업이다.

# blog > views.py
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Post
from rest_framework import serializers
from drf_spectacular.utils import extend_schema

# views.py 수정을 통해 api/schema/swagger-ui 문서를 변경할 수 있도록 수
# 이 코드는 원래 .serializers.py로 작성이 되었어야 하는 파일입니다.
class PostSerializer(serializers.Serializer):
    title = serializers.CharField()
    content = serializers.CharField()


@extend_schema(
    methods=["GET", "POST"],
    request=PostSerializer,
    responses={200: PostSerializer(many=True)},
)
@api_view(["GET", "POST"])
def blog_list(request):
    serializer = PostSerializer(Post.objects.all(), many=True)
    return Response(serializer.data)
  • extend_schema : 스키마 생성을 위한 추가 메타데이터를 제공하는데 사용
  • class PostSerializer : serializers.py에 있어야 하는 내용으로 Post 모델 인스턴스의 직렬화 및 역직렬화에 포함되어야 하는 필드를 정의
  • @extend_schema 함수 : GET 및 POST 요청을 모두 처리하고, 요청 본문은 POST 요청의 경우 PostSerializer를 준수해야 하며, 성공적인 응답(상태 코드 200)은 PostSerializer를 사용하여 직렬화된 Post 객체 목록을 반환
  • @api_view : request를 매개변수로 받아, Post모델의 몯느 인스턴스를 직렬화하여 응답으로 반환
  • blog_list 함수
    • Post 모델의 모든 인스턴스를 조회하고, PostSerializer를 사용하여 직렬화
    • many=True : 여러 인스턴스를 직렬화할 수 있음
    • 최종적으로 직렬화된 데이터를 Response객체에 담아 반환

최종 API 명세서의 모습이다. http://127.0.0.1:8000/api/schema/swagger-ui/#/



profile
익숙해지기 위해 기록합니다

0개의 댓글