Django 와 DRF 같이 쓰기.

악식·2023년 8월 15일
0

Situation

django 웹 어플리케이션을 구성할 때, API 를 쉽게 개발하기 위해서 DRF(Django RESTful Framework)를 사용합니다. django + DRF 를 백엔드 API 서버로만 사용하기 위해 단독 구성할 수도 있지만, django 는 기본적으로 풀스택 프레임워크입니다.

웹 페이지를 렌더링하기 위한 일반적인 뷰와, API 를 개발하기 위한 API 뷰를 같이 개발할 경우에 대해서 생각해봅시다.

Problem

Django 에는 app 이라는 단위로, 기능을 분리해서 구성하게 됩니다.. Domain Driven Development과 비슷한 맥락을 갖고 있습니다. 가독성과 유지보수성 측면에도 강점이 있고, 이 app 만 따로 배포해서 사용하는 것도 가능합니다.

다음과 같은 사례를 생각해봅시다.

/mysite/ # root app
/app-a/
/app-b/
manage.py 
... 
# /mysite/urls.py
urlpatterns = [
	path('app-a/', include('api-a', include('app-a.urls')),
    path('app-b/', include('api-b', include('app-b.urls')),
    ...
]

api 를 app 들 내부에 작성할 경우, url pattern는 다음과 같을 것입니다.

[	
  	<!-- 일반적인 웹 페이지들 --> 
  	"app-a-index" : "/app-a/", 
  	"app-b-index" : "/app-b/",
  
  	<!-- DRF는 Browsable API 를 제공한다. --> 
	"app-a-api-root" : "/app-a/api/",
  	"app-a-api-some-api" : "/app-a/api/some-api/",
  	"app-b-api-root" : "/app-b/api/",
    "app-b-api-some-api" : "/app-b/api/some-api/",
]

이제 api-root 들로 접근하기 위한 api-root 를 추가해주겠습니다. DRF가 browsable api 를 제공하니만큼, api 를 탐색할 수 있도록 만들어주는 것입니다. 이 글에서 다뤘습니다.

[	
  	"app-a-index" : "/app-a/", 
  	"app-b-index" : "/app-b/",
  
  	<!-- api root 는 app-a, app-b 어느 쪽에도 속하지 않기 때문에 mysite 에 직접 작성할 수 밖에 없다. --> 
  	"api-root" : "/api/",
	"app-a-api-root" : "/app-a/api/",
  	"app-a-api-some-api" : "/app-a/api/some-api/",
  	"app-b-api-root" : "/app-b/api/",
    "app-b-api-some-api" : "/app-b/api/some-api/",
]

api root 가 app-a-api-root 와 app-b-api-root의 상위 리소스라는 느낌을 주는데에도 불구하고, url 패턴에서는 일관성이 떨어집니다.
실제로 browsable api 에서 표시되는 내용을 살펴보겠습니다.

/api/ 로 들어가 api 목록을 받았는데, 하위의 항목들이 /api/ 로 시작하지 않고 완전히 다른 경로를 주고 있습니다.

만약, api 라는 별개 app 을 만든 뒤, 그 app 에 api 를 전부 구성하게 되면 위와 같은 문제는 사라지지만, 이번엔 도메인과 api 가 멀어지는 문제가 발생합니다. app-a,b 에 사용되는 api 를 api 라는 별개 앱에 개발하게 되면 app-a, b와 api 는 서로 의존하게 됩니다. (app-a, b가 렌더링하는 템플릿 페이지들이 api의 api를 사용할 것이기 때문에)

심지어 api는 app-a, app-b 양쪽에 의존하기 떄문에, app-a나 app-b 한 쪽만 사용하고 싶어도, 세 개의 앱을 전부 설치 해야 합니다. 좋은 구조라고 보긴 어려울 것 같습니다.

Solution

다음과 같은 방법을 생각해봤습니다.

  1. api 는 app 내부에 개발한다.
  2. api 의 urls 를 urls.py 내부에 개발하지 않고 분리한다. (urls_api.py)
  3. mysite.urls(root app) 에서 urls_api.py 를 따로 추가한다.
# /mysite/urls.py

url_api_patterns = [
    path('app-a/', include('app-a.urls_api')),
    path('app-b/', include('app-b.urls_api')),
]

urlpatterns = [
    path('app-a/', include('app-a.urls')),
    path('app-b/', include('app-b.urls')),

    # API views
    path('api/', views.api_root, name='api-root'),
    path('api/', include(url_api_patterns)),
]

이제, api url 구조를 안정적으로 유지하면서 도메인과 api 간의 거리도 정상적으로 유지할 수 있습니다.


django , DRF 를 같이 사용할 경우 어떤 식으로 URL 을 구성하는 것이 좋을지 고민해봤습니다. 컨벤션이나 베스트 프랙티스는 찾지 못했으나, app 내부에 같이 개발하거나, api app을 따로 개발하는 것이 일반적으로 보입니다. monolithic 한 어플리케이션의 경우에는 위의 형태가 괜찮아보입니다.

browsable api 가 없는 환경에서는 고민한 적이 없었던 문제입니다.

profile
Wandering wondering.

1개의 댓글

comment-user-thumbnail
2023년 8월 15일

정보 감사합니다.

답글 달기