DRF는 이제 잊으세요. Django-ninja 의 탄생



프로그래밍 언어도, 웹 프레임워크도  선택할 수 없을 정도로 많이 생겨났습니다. 10년 전까지만 해도 이러지 않았지만, 오픈소스가 많아지고 집단지성이 힘을 가지면서 서로의 좋은 면을 가지고 오기 시작한 것 같습니다. FastAPI는 매우 Hot하지만, Django 를 사용하는 엔지니어는 기존 코드를 FastAPI로 전부 이전 하기가 쉽지 않습니다. 


우선, FastAPI로 테크트리를 바꿔 타려면 이걸 고민해야 합니다.

  • Django Serializer / Deserializer 변경
  • Django ORM을 SQLAlchemy로 변경
  • 프로젝트 스켈레톤 변경
  • DB 모델 작성 
  • 등등등..


거의 새로 만드는 것과 다름 없습니다.

그래서 나왔습니다. Django-ninja : https://django-ninja.rest-framework.com/


아직 0.13 버전대를 유지하고 있지만, 프로덕션 레벨로 서비스하기에 충분한 기능을 제공하고 있습니다. 상당 부분의 코드가 FastAPI에서 영감을 받아 작성한 프레임워크로 FastAPI가 성숙해 지고 있는 만큼 Django-ninja도 성숙해 질 것 입니다.



Django-ninja가 지원하는 기능을 한번 알아볼까요?



1. Pydantic 사용 가능

느려터진 Django Serializer 를 버릴 수 있게 되었습니다. DRF(Django Rest Framework)에서 지원하고 있는 장고 시리얼라이져는 너무 느립니다. 이 속도를 고민해 보지 않은 사람은 아마 없을거에요. 아직도 사용하고 계신가요? 아직도 고민 하고 계신가요? 이제 Django-ninja와 함께 Pydantic을 사용하세요!


Pydantic 공식 문서에 있는 퍼포먼스 벤치마크 입니다.


12.3배 느린 장고 레스트 프레임워크...

 



2. Swagger 자동 생성


FastAPI 에서 자동으로 생성해주는 Swagger .. 이제 Django-ninja에서도 만나 보실 수 있습니다. DRF도 비슷한 것을 지원하고 있었습니다. 헤당 엔드포인트로 들어가면 자세히 API 스펙을 보여주는 정도 입니다. 아래 같이 생겼습니다.

하지만, Django-ninja는 Swagger를 자동 생성해 주고, Django 인증을 사용할 수 있도록 해주며, 한번 로그인하면 쿠키로 인증하기 때문에 요청할때 마다 토큰을 일일이 넣을 필요가 없습니다. 어쩌면 JWT로 인증하는 FastAPI 보다 더 편할 수도 있습니다. 

위는 Swagger 입니다. 어떠신가요? 더 직관적이고 사용하고 싶게 생기지 않았나요? 



3. Async 지원

Django ORM 은 Sync로 작동합니다. 그래서 Async로 작동하게 만들려면 기존 방법과는 다르게 해야 합니다.

from asgiref.sync import sync_to_async

results = await sync_to_async(Blog.objects.get, thread_sensitive=True)(pk=123)

위는 Django ORM을 비동기로 작동시킨 것입니다. 어떠신가요? 기존 ORM 에 익숙하신 분들은 정말 싫으실 것 같지 않나요? Django에서 그래서 마법같이 만들낸 것이 sync_to_async 입니다.

함수로도 사용할 수 있고 데코레이터로 사용할 수도 있습니다.

from asgiref.sync import sync_to_async

async_function = sync_to_async(sync_function, thread_sensitive=False)
async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True)

@sync_to_async
def sync_function(...):
    ...

asyncio로 작동하기 때문에 sync_function 안에서는 await를 사용할 수 없습니다. 그냥 sync로 코딩하시면 해당 함수가 async로 작동하기 때문에 Django ORM도 편하게 사용하실 수 있습니다. 

sync_to_async(sync_function, thread_sensitive=True)

위와 같이 thread_sensitive 라는 키워드 아규먼트가 있는데 기본 값은 True 입니다. True로 하면 기존 쓰레드를 그대로 사용하게 되고 False로 하면 새로운 쓰레드를 생성해서 사용하며 인보케이션 후 닫힙니다. 


Django-ninja 에서는 FastAPI와 같이 데코레이터로 된 URL 패스를 지정하게 되는데요. 그때 sync_to_async 데코레이터와 함께 쓰시려면 순서가 중요합니다.

@sync_to_async
@router.get("/hello", response=HelloWorld)
def hello_function(request, status: str = "all", page: int = 1, start_date: str = None, keyword: str = None):
    max_item_in_page = 20

Sync_to_async를 먼저 쓰시고 Path를 설정해 주세요. Django Channel을 사용해서 ASGI 앱으로 만들어 사용하는 것도 방법입니다. 

Django Channel : https://channels.readthedocs.io/en/stable/ 


@sync_to_async가 있드시.. @async_to_sync 함수/데코레이터 도 있습니다.



4. Versioning과 CSRF


DRF도 마음먹으면 버저닝 손쉽게 할 수 있지만, 버저닝에 따라 Swagger를 다르게 출력할 수 있습니다. 엔드포인트 별로도 Swagger 페이지를 다르게 만들 수도 있습니다. 백엔드 앱이 어느정도 시간이 지나면 사용하지 않는 엔드포인트도 생기고 수백개의 엔드포인트가 생성됩니다. 페이지를 다르게 해서 볼 수 있게끔 해줘야 프론트엔드 엔지니어들과 협업이 수월해 집니다. 


Django-ninja 는 기본적으로 CSRF를 검사하지 않습니다. 

물론, 검사를 하게 만들수도 있습니다. 



5. Model에서 Schema 뽑아내기


기존에 가지고 있는 Model에서 편하게 스키마를 뽑아 낼 수 있습니다. 일일이 다 쓰기가 쉽지않은데 멋진 기능을 선사합니다. 멋진 기능은 아래 링크에서 확인할 수 있습니다.




귀찮으신 분들을 위한 샘플.



오묘한 점도 하나 있긴 한데요. 구현이 가능해서 단점이라고 하긴 그렇고... Django는 특성상 미들웨어에서 try...catch로 에러 핸들링을 하기 쉽지 않은데요. 그래서 커스텀 에러핸들링을 만들어 줄 수 밖에 없습니다. 복잡 미묘한 방법으로 지금 사용하고 있긴한데, 버전이 올라가면서 더 편해질 것이라 생각합니다. 추후에 하는 방법을 올려 보도록 하겠습니다.


태어난지 얼마 안된 신생 프레임워크 이지만, FastAPI의 성숙도를 차용해 왔기 때문에, 지금 현 상황에서도 사용해 볼 가치가 충분히 있는 프레임워크 인듯합니다. 강의를 만들어 보고 싶은 정도 입니다. 


Django에 광범위한 생태계 각종 라이브러리들, Django ORM 이 지원하는 다양한 기능 및 DB 스키마 버저닝... 안정적인 웹 서버 서빙능력 등을 포기하고 싶지 않은 상황에 위와 같은 장점을 사용하고 싶다면, 지금 한번 사용해보시는 것이 어떨까요? 강추합니다!



  • [[a.original_name]] ([[a.file_size | fileSizer]])
좋아요[[ postLike | likePlus ]]
공유
라이언

“Lead Python Engineer”

댓글 [[totalCommentCount]]
[[ comment.author__nick_name ]] [[ comment.datetime_updated | formatDate]] (수정됨)

[블라인드 처리된 글 입니다.]

답장
[[ sub.author__nick_name ]] [[ sub.datetime_created | formatDate ]] (수정됨)

취소
댓글을 남겨주세요.
'파이썬' 관련 최신 포스트
[[ post.title ]]
[[ post.datetime_published_from | DateOnly ]]