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.:
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.
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!
Turns out that you can control this by changing the tags in a view, as per OpenAPI specification: https://swagger.io/docs/specification/grouping-operations-with-tags/
So, with drf-spectacular, you can use the extend_schema decorator to achieve this, e.g.:
from drf_spectacular.utils import extend_schema
class CustomTokenObtainPairView(TokenObtainPairView):
"""
Takes a set of user credentials and returns an access and refresh JSON web
token pair to prove the authentication of those credentials.
"""
@extend_schema(
operation_id="jwt_obtain",
....
tags=["aTestTag"]
)
def post(self, request, *args, **kwargs):
# whatever
So you have to use this decorator to extend the schema in each view that you want to put into a custom group.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With