SoftWare

[Django] Ninja Swagger API 설치부터 활용까지

chesleashin 2023. 8. 31. 10:49
  • Ninja-API
    올해 들어 참여한 2개의 프로젝트에 Back-end를 Django를 사용했는데, 모두 Ninja-API를 통해 상당히 편하게 개발했다.
    Back-end / Front-end로 분리한 3-tier 구조로 개발하기에 좋은 툴이라 앞으로의 개발에도 종종 사용할 것 같다.
     - Ninja 공식사이트 : https://django-ninja.rest-framework.com

  • Ninja-API 장점 
    1) Django에서 좋은 코드, 좋은 개발환경을 목표로, 기능(API) 단위 개발에 집중할 수 있도록 해줌
    2)  Front-end 개발자와 Back-end 개발자 사이에, 만든 API가 기능을 잘 하는지, 형식은 무엇인지 등을 확인하고 소통하기에 편리 (url 접근 용이, request/response body 형식 확인)

    Django에서 기본적으로 제공하는 User 모델을 사용하여 
    재사용성과 테스트 용이성 등의 장점을 얻을 수 있었고. 
    (Fat Model, Skinny View) 

    FastAPI의 데이터 값 검증에 사용되는 Pydantic을 router api나, service layer에서 코드를 잘 분리하여 비즈니스 로직에 집중하여 
    더 간결하고 가독성이 좋은 코드 작성 등의 장점을 얻을 수 있었다. 
    (Thin Models, Fat Functions) 

    상속받아 만든 Ninja의 Schema 모듈을 통한 유효성 검사 편의성,  @property is_staff나, has_permission과 같은 형태가 기본 제공되는 것을 활용하면 편리하다는 장점이 있다!

 

  • Ninja 라이브러리 설치 명령어
$ pip install django-ninja

 

  • Ninja urls.py에 추가하기
# urls.py
 
from ninja import NinjaAPI
 
api = NinjaAPI()
 
# 방법 1)
@api.get("/add")
def add(request, a: int, b: int):
    return {"result": a + b}
 
urlpatterns = [
    path("admin/", admin.site.urls),
    # 방법 1) 같은 urls.py 파일에 함수를 구현하는 방식.(파일은 최대한 기능 단위로 구분하는 것이 좋으므로 추천 X)
    # path("api/", api.urls),   # url은 지정하기 나름! 우리 프로젝트에서는 'ninja-api/'로 router를 지정해 사용했다.
     
    # 방법 2) myWEB 폴더 내에 apis.py 파일을 생성하여 해당 파일에
    path('', include('myWEB.urls')),
    path('ninja-api/', apis.urls),]

 

  • apis.py에서 기능(API) 구현
# apis.py
 
from ninja import NinjaAPI
 
api = NinjaAPI()
 
# 방법 1)
@api.get("/add")
def add(request, a: int, b: int):
    return {"result": a + b}
 
urlpatterns = [
    path("admin/", admin.site.urls),
    # 방법 1) 같은 urls.py 파일에 함수를 구현하는 방식.(파일은 최대한 기능 단위로 구분하는 것이 좋으므로 추천 X)
    # path("api/", api.urls),   # url은 지정하기 나름! 우리 프로젝트에서는 'ninja-api/'로 지정해 사용했다.
     
    # 방법 2) myWEB 폴더 내에 apis.py 파일을 생성하여 해당 파일에 API 함수 작성
    path('', include('myWEB.urls')),
    path('ninja-api/', apis.urls),]
        
 
  • API 함수 구현 
    - 내가 추가한 App(aka. "myWEB") 폴더 내에서  get/post 구분하여 함수 구현
# apis.py
from ninja.router import Router
 
# 같은 폴더 내 위치한 models.py/schemas.py 파일 내 class나 function 사용할 수 있도록 import
from .models import *
from .schemas import *
 
jeoncham = Router()    # 이 라우터의 이름 선정해 변수로 지정
 
# GET 함수 예시 1)
@jeoncham.get("addFunction1")
def add(request, a: int, b: int):
    return {"result": a + b}
 
# POST 함수 예시 2)
@jeoncham.post("addFunction2")
def add(request, body: numberInfoSchema):
    if request.method == 'POST':
        try:
            result = a + b
            return JsonResponse({'returnCode': 'OK', 'message': 'success', 'data':  result})
        except Exception as e:
            print('exception : ' + str(e))
            if str(e) == "token is unauthorized.":
                return JsonResponse({'returnCode': 'NG', 'message': str(e)}, status=401)
            return JsonResponse({'returnCode': 'NG', 'message': str(e)})
 
  • Schemas.py 활용
    - 위와 같은 폴더 내 schemas.py 파일을 생성한다
    - apis.py 를 통해 구현한 API를 통해 Front-end와 Back-end가 통신할 때, body 형식을 schema에 미리 정의해두는 곳으로, import가 필요하다.
from ninja import Schema
 
class numberInfoSchema(Schema):
    a: int
    b: int

 

  • 접속 URL: 도메인/ninja-api/docs