djangodjango-rest-frameworkdrf-yasg

How to handle namespace API versioning with DRF-YASG


In my project we want to have multiple versions of same api so as to support backward compatibility. Right now we are using drf-yasg's swagger url at /api/doc/ While our apis are /api/vehicle/$ /api/warehouse/

And then each of the app vehicle and ware house have their own endpoints..

Now we want to do versioning as /api/v1/doc /api/v2/doc /api/v1/vehicle /api/v2/vehicle /api/v1/warehouse

Goal is that /v1/doc should show v1 of both vehicle and ware house while/v2/doc should show only v2 of vehicle since only vehicle app has some apis with v2.... How to achieve this

I tried adding default version v1 initially in drf settings. But that resulted in no listing being shown in swagger view


Solution

  • I know this is an old question, but I ran into this same issue recently and was able to resolve it like so,

    in my root app urls

    # myapp/urls.py
    
    ...
    path('api/v1/', include('api.v1.urls'),
                       name='v1'),
    path('api/v2/', include('api.v2.urls'),
                       name='v2'),
    ...
    

    then I created an app specifically to handle all api routes with different versions, inside this app i have a module for each of the versions I have as well as the urls for swagger/redoc like that

    api/
        __init__.py
       |
       v1/
         |
          __init__.py
          urls.py
       v2/
         |
          __init__.py
          urls.py
    

    In each of the version urls, I added the urls for the specific app apis and the urls for docs like so

    # app/v1/urls.py
    
    from django.urls import path, include
    from drf_yasg import openapi
    from drf_yasg.views import get_schema_view
    
    urlpatterns = [
        path('app1/', include('app1.api.v1.urls'), name='app1-api-v1'),
        path('app2/', include('app2.api.v1.urls'), name='app2-api-v1'),
        path('app3/', include('app3.api.v1.urls'), name='app3-api-v1'),
    ]
    
    schema_view = get_schema_view(openapi.Info(
        title="My API",
        default_version='v1',
        description="My REST API documentation",
        contact=openapi.Contact(email="dev@myapp.com"),
    ),
        public=True, patterns=urlpatterns)
    
    urlpatterns += [
        path('swagger/',
         schema_view.with_ui('swagger', cache_timeout=0),
         name='schema-swagger-ui-v1'),
        path('redoc/',
         schema_view.with_ui('redoc', cache_timeout=0),
         name='schema-redoc-v1'),
    ]
    

    Did the same for api/v2/urls.py with the corresponding changes to the urls and naming. This way I had 2 separate urls for each of version of the api docs.

    Hope this helps!