Python (with. Code)/Django-ninja

[Django Ninja] 설계 패턴 정하기 (feat. 리팩토링)

yubi5050 2023. 7. 1. 17:20

서론

진행 중인 Django Ninja 프로젝트에서 리팩토링을 진행 하며, 코드의 중복을 줄이거나, 객체지향적 구조로 변경 등의 방향성 외에도, 프레임워크에 맞는 특정 패턴을 기준으로 삼아보려고 하였다.

 

Django에는 "Fat Model Skinny View"라는 대표적인 패턴이 있고,

FastAPI는 주로 "Thin Models, Fat Functions"  패턴을 통해 코드의 직관성을 높이는데 집중한다.

(참고로 Django Ninja는 FastAPI의 등장을 주 Motivation 중 하나로 얘기하고 있음)

 

Django-Ninja 프로젝트에서 Django의 "Fat Model Skinny View" 설계 패턴이 어울릴까?

 

해당 글에서는 

  • Django(DRF)의 Fat Models, Skinny View 패턴
  • FastAPI 에서의 Thin Models, Fat Functions 패턴

의 특징에 대해 정리해보고, Django Ninja 에서 적절한 설계 패턴은 무엇일지 고민한 과정을 정리해본다.

 

Fat Model Skinny View 패턴

Django, DRF의 Model에 기능을 모으고(Fat), View는 단순히 Model을 조작하며 요청/응답에 집중하는 패턴

 

👉 특징

  • Model 클래스가 비즈니스 로직과 데이터 관련 작업을 포함함
  • View는 Model 함수들을 사용 및 조작하며, 요청/응답에 집중
  • + DRF 에서는 Serializer를 사용하여, 유효성 검사 / DB 작업 을 담당하며, View의 역할을 보다 집중 시킨다.
  • + Django에서 Create(), Update() 등의 CRUD method를 Model에 구현
  • 다른 View나 App에서도 필요시 Model 메서드에 접근하여 사용 가능 (코드 중복 ↓ / 재사용성 ↑)
  • 일반적으로 View(서비스)가 커지면서, 다양한 App 도메인 코드가 섞이면 관리가 어려움 (코드 가독성 )
  • 모델 내 선언으로, 모델 메서드에 대한 단위 테스트가 쉬움 (테스트 용이)
  • Tip : @Property 옵션 사용하여 가상의 필드 생성도 가능 

 

Thin Models, Fat Functions 패턴

FastAPI는 주요 비즈니스 로직을 View나, Router에 부여하고, Model은 데이터 구조 정의 및 연결 역할만 수행

 

👉 특징

  • View(Service), Router에서, 비즈니스 로직, 유효성 검사(Pydantic), 데이터 처리 등을 수행
  • Model은 DB와의 상호작용, 데이터 구조 정의 하는 역할만 수행
  • 비즈니스 로직이 View(Service)에 모이기 때문에, 구조가 복잡해 질 수는 있음
  • 함수/파일 분리, 레이어 분리 등으로 보다 간결하면서 직관적인 코드를 얻을 수 있음 (간결성 ↑ / 직관성 ↑)
  • 또한 Type 힌팅과, 자동 문서화 기능등을 통해 개발자가 코드를 이해하고 유지보수 편의성에 집중 (개발자 생산성 ↑)

 

Django Ninja 에서는 어떤 패턴이 합리적일까?

위 'Fat Model, Skinny View'와 'Thin Models, Fat Functions' 두 특징을 비교해보며, 

결국 공통의 궁극적인 목표는 좋은 코드, 좋은 개발환경을 위한 것이라는 생각이 들었고, 

 

최종적으로 Django-Ninja를 프로젝트에 사용하면서 자연스헙게

 

Django에서 기본적으로 제공하는 User 모델을 사용하여

@property is_staff나, has_permission과 같은 형태가 기본 제공되는 것을 활용하며

재사용성과 테스트 용이성 등의 장점을 얻을 수 있었고. (Fat Model, Skinny View)

 

FastAPI의 데이터 값 검증에 사용되는 Pydantic을

상속받아 만든 Ninja의 Schema 모듈을 통한 유효성 검사 편의성, 

router api나, service layer에서 코드를 잘 분리하여 비즈니스 로직에 집중하여

더 간결하고 가독성이 좋은 코드 작성등의 장점을 얻을 수 있었다. (Thin Models, Fat Functions)

 

 

물론 한쪽 방향성의 규칙으로 정하여, 개발하는 것이 더 일관적이고, 통일성 있는 형태의 코드를 작성할 수 있겠지만,

개인적으로는 두 방향성 중 1개를 온전히 따르는 것보다, 각각의 장점을 잘 살려 진행해 보는 것이 좋은 방향이란 생각이 들었다.