Django REST Framework - multiple models / APIs?

django, django-rest-framework, django-testing

Solution

I am building a restful API also with Django like you. What I am doing is letting applications be independent like in your last example.

We have a “core” django application, where we have the api_root in the views and a file named “apis_urls.py” where we organize all the URLs from the different apps.

We also have in this “core” app a file “apis_filters.py” where we have the filters that any app with API can use and “apis_permissions.py” to manage the permissions to use the apis and import on the other apps.

So at the end we are working like this:

project root
|
|-app1 / models.py .... views.py (app1 API), serializers.py, tests.py
|
|-app2 / models.py .... views.py (app2 API), serializers.py, tests.py
|
|-app3 / models.py .... views.py (app3 API), serializers.py, tests.py
|
\- core / views.py (api_root), apis_urls.py,  apis_filters.py,  apis_permissions.py

We make all the tests in their corresponding apps.

And having the apis_urls.py allows us to have all the API URLs like:

http://localhost/api/v1/example1
http://localhost/api/v1/example2

In the main urls.py we have:

url(r'^api/v1/', include('core.apis_urls', namespace='api')),

And on the core app, on the “apis_urls.py”:

urlpatterns = patterns(
'',
    ####### Users Urls
    url(r'^users/$', users_views.UserListAPIView.as_view(), name='users-list-api'),
    url(r'^me/$', users_views.LoggedUserRetrieveUpdateAPIView.as_view(), name='logged-user-detail-api'),
    url(r'^users/(?P<username>[\w.@+-]+)/$', users_views.UserRetrieveAPIView.as_view(), name='users-detail-api'),

    ####### Comments Urls
    url(r'^comments/(?P<pk>[0-9]+)$', comments_api_views.CommentCreateAPIView.as_view(), name='comments-create-api'),
)

I hope this help, is the way I found it more organize.

Problem

We use Django to build web-app backend, providing RESTful API for Ember app. So (evolutionally) we started with the following simple structure: ``` project root | |-app1 / models.py .... no views.py | |-app2 / models.py .... no views.py | |-app3 / models.py .... no views.py | \- restapi - provides REST API for app*: huge views.py, huge serializers.py, huge test.py ``` This is easy to use, especially with the DRF's browsable view: ``` @api_view(['GET']) def api_root(request, format=None): return Response( { 'users': reverse('current-user-detail', request=request), 'interfacesettings': reverse('interface-settings', request=request), ............................................................ 'preferences': reverse('preferences', request=request), } ) ``` Shortly we have got enough models/APIs to make our restapi.app way too complex and messy, and we started to consider using something more logical: ``` project root | |-app1 / models.py .... views.py, serializers.py, tests.py | |-app2 / models.py .... views.py, serializers.py, tests.py | |-app3 / models.py .... views.py, serializers.py, tests.py | \- we do not need rest api anymore (but where will we put our api_root?) ``` On the other side, we have now all complicated tests (that involve few models) in one place which is convenient. And we reuse serializers's functions a lot. And we have one api_root. So probably we may have something like this: ``` project root | |-app1 / models.py .... views.py (app1 API), serializers.py, tests.py | |-app2 / models.py .... views.py (app2 API), serializers.py, tests.py | |-app3 / models.py .... views.py (app3 API), serializers.py, tests.py | \- restapi - views.py (api_root), tests.py for complicated tests and serializers.py for common functions ``` Which approach is better? And what are the common best practices here? Is there any open project we can take a look?

Original source