Search code examples
djangodjango-rest-frameworkswaggerswagger-uiopenapi

Custom Grouping on OpenAPI endpoints with Django Rest Framework


I have a Django project and I am using Django REST framework. I am using drf-spectacular for OpenAPI representation, but I think my problem is not tied to this package, it's seems a more generic OpenAPI thing to me (but not 100% sure if I am right to this).

Assume that I have a URL structure like this:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include([
        path('v1/', include([
            path('auth/', include('rest_framework.urls', namespace='rest_framework')),
            path('jwt-auth/token/obtain', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
            path('jwt-auth/token/refresh', CustomTokenRefreshView.as_view(), name='token_refresh'),
            path('home/', include("home.urls"))
        ]))
    ])),

    # OpenAPI endpoints
    path('swagger/', SpectacularSwaggerView.as_view(url_name='schema-swagger-json'), name='schema-swagger-ui'),
    path('swagger.yaml/', SpectacularAPIView.as_view(), name='schema-swagger-yaml'),
    path('swagger.json/', SpectacularJSONAPIView.as_view(), name='schema-swagger-json'),
    path('redoc/', SpectacularRedocView.as_view(url_name='schema-swagger-yaml'), name='schema-redoc'),
]

In the corresponding swagger UI view, I get all endpoints grouped under api endpoint, e.g.: enter image description here

If add more endpoints under v1, all go under the api endpoint.

What I want to achieve is, to have the endpoints in Swagger grouped differently, e.g. by app. So I'd have home, jwt, another_endpoint, instead of just api, so it will be easier to navigate in Swagger (when I add more endpoints, with the current method it's just showing a massive list of URLs, not very user friendly).

I've read that those groups are being extracted from the first path of a URL, in my case this is api, so if I change the URL structure, I could achieve what I need.

But isn't there another way of doing this? I want to keep my URL structure, and customize how I display this with OpenAPI, so in the end I have a swagger that groups the endpoints by app, so it's easier to navigate and find what you are looking for.


Solution

  • you are making it harder than it needs to be. In the global settings you can specify a common prefix regex that strips the unwanted parts. that would clean up both operation_id and tags for you. In your case that would probably be:

    SPECTACULAR_SETTINGS = {
        'SCHEMA_PATH_PREFIX': r'/api/v[0-9]',
    }
    

    that should result in tags: home, jwt-auth, swagger.json, swagger.yaml

    the tags on @extend_schema is merely a convenience to deviate from the default where needed. it would be cumbersome to do this for every operation. see the settings for more details:

    https://drf-spectacular.readthedocs.io/en/latest/settings.html

    for even more elaborate tagging you can always subclass AutoSchema and override get_tags(self) to your liking. cheers!