적당히 타협한 Django 아키텍처

Django는 아래와 같은 특성 때문에 클린 아키텍처와 DDD를 적용하기 어렵다. (프레임워크의 의도와 다르게 코드를 작성해야하는 경우가 생긴다.)
- 액티브 레코드 패턴을 사용하는 Model -> 도메인 모델로만 사용하기 어렵고 DB 테이블 구조와 밀접하게 연관
- 비즈니스 로직과 엮여있는 View -> 뷰에 비즈니스 로직을 구현하기 쉬운 구조
- Django ORM -> 데이터를 가져오고 저장하는 방식이 특정 ORM 코드에 종속됨
차선으로 DDD를 선택적으로 적용한 Layered 아키텍처를 생각한다. MSA로 확장 가능성을 고려해서, 적당히 타협한 아키텍처를 생각해본다.
- app 단위로 Bounded Context를 정의하고
- Domain Logic은 Model에 두고(Rich Domain Model)
- Service Layer(User cases)에 Application Logic을 분리한다.
- 도메인 객체 사용
- 엔티티 조회/저장
- 트랜잭션 보장
- 사용자 인증/인가
- 입력값 검증
- Domain Event의 Listener
- 로깅
- API 게이트웨이 패턴을 사용(또는 준비)한다. 게이트웨이 컴포넌트의 API에서 서비스의 API(또는 프로시저)를 조합한다.
DRF를 사용한다면 아키텍처의 혼란은 더 가중될 수 있다.
- 시리얼라이저의 역할이 너무 많다. 원래 목적인 직렬화/역직렬화 외에도, 비즈니스 로직을 다루고 데이터 저장에 관여한다. 심지어 DRF의 뷰도 시리얼라이저에 강하게 종속되어있다.
- 비즈니스 로직을 책임질 곳이 불분명하다. 아래 모듈은 각각의 이유로 (비즈니스 로직을 구현하기에) 적합하거나, 적합하지 않다.
- Model - Django 설계 철학에 적합하나, Active Record 의 한계로 DDD 등 적용 어려움
- View - 프레젠테이션 레이어로 기능하는게 이상적이나 역시 Django 특성상 비즈니스 로직을 포함하기 쉬움
- Serializer - 코어는 데이터 직/역직렬화 기능이나, 편의를 위해 비대해졌다. 데이터 접근 및 저장하는 Repository, 입출력 형식을 검증하는 Validator, 심지어 request 객체를 다루는 Controller로서 쓰일 수도 있다. 어떤 형태로든 비즈니스 로직이 섞이기 쉽다.
refs
- Clean Architectures in Python - presented by Leonardo Giordani - YouTube
- GitHub - HackSoftware/Django-Styleguide: Django styleguide used in HackSoft projects
- Django와 DDD가 함께하기 어려운 이유 (7/11 보완) | by Junha Baek | junhabaek
- Django와 Layered Architecture 사이에서 타협점 찾기 | by 아테나스랩 | 아테나스랩 팀블로그 | Medium
- 백엔드 서버 Application Layer의 개요, 역할, 구현 방식 | junhabaek
- Django는 죄가 없다
- Django, DRF Serializers - serializer 파헤치기, 왜 serializer? response가 만들어지기 까지