In this tutorial I will explain why you should use OpenAPI and how to add it to your Django REST API project.

What's the Difference Between Swagger and OpenAPI?

Swagger is a set of tools for building and documenting RESTful APIs. It includes a specification for describing the structure and behavior of an API, as well as tools for generating interactive API documentation and client libraries in various programming languages.

OpenAPI is the successor to Swagger, and is a specification for describing RESTful APIs. Like Swagger, OpenAPI provides a way to describe the structure and behavior of an API, but it is more flexible and extensible than Swagger, and has gained widespread industry adoption.

Swagger and OpenAPI are closely related, with Swagger being the original project that evolved into OpenAPI. OpenAPI is now the industry-standard for describing RESTful APIs, and many tools and libraries that were originally built for Swagger now support OpenAPI as well. In fact, many people use the terms Swagger and OpenAPI interchangeably, although technically they refer to different things.

What is the use of OpenAPI?

OpenAPI is a specification for describing the structure and behavior of RESTful APIs. The main purpose of OpenAPI is to provide a standardized way for developers to describe and document their APIs, making it easier for other developers to understand and use those APIs.

Some of the key benefits of using OpenAPI include:

Improved documentation: OpenAPI allows developers to generate detailed documentation for their APIs automatically, based on the API description. This makes it easier for developers to understand how the API works and how to use it.

Better collaboration: OpenAPI provides a standardized way for developers to communicate about their APIs, making it easier for different teams to work together on API development and integration.

Code generation: OpenAPI can be used to generate code stubs and client libraries in various programming languages, based on the API description. This can save developers a significant amount of time and effort when implementing an API.

Tooling ecosystem: OpenAPI has a large and growing ecosystem of tools and libraries that support the specification, including validators, code generators, documentation generators, and more. This makes it easier for developers to work with APIs that use the OpenAPI specification.

Project Setup

For the DRF setup please refer to the Building a restful api with Django REST framework tutorial.

In this article we will use the project which we setup there.

Code for this tutorial can be found here: https://github.com/appliku/drf-openapi-tutorial

Install and setup drf-spectacular

Open the terminal in the project root and install the package drf-spectacular:

pip install drf-spectacular

Open project/settings.py and add drf_spectacular to the INSTALLED_APPS:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
        'drf_spectacular',  # new
    'main',
]

Make sure to add the REST_FRAMEWORK variable in settings:

REST_FRAMEWORK = {
    # YOUR SETTINGS
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

Add the variable SPECTACULAR_SETTINGS:

SPECTACULAR_SETTINGS = {
    'TITLE': 'TODO List API',
    'DESCRIPTION': 'API documentation for our app',
    'VERSION': '1.0.0',
    'SERVE_INCLUDE_SCHEMA': False,
    'COMPONENT_SPLIT_REQUEST': True
    # OTHER SETTINGS
}

Look at one important key in this dictionary: COMPONENT_SPLIT_REQUEST.

It will make Spectacular generate separate definitions for read, create and update requests. This in turn allows client code generation to make separate types for read obejcts, create objects and patch/update objects.

Here are some examples of enabling COMPONENT_SPLIT_REQUEST:

  • if a serializer has a read_only=True field, then such a property for this field will only exist on the object that is returned by the API.
  • the same way a serializer field with write_only=True attribute will only exist on type of object you pass to create an instance(PUT operation) or update (PATCH operation).
  • on the definition/type for PATCH operation pretty much all fields will be optional.

This allows the developer of client app to have exactly correct attributes on those objects, type checking and not doing workarounds around the generated types.

Add URLs for API Schema:

In your project/urls.py (or other path where your root URLConf is specified) add these lines to the urlpatterns list:

from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView

urlpatterns = [
    # ...
    # API Schema:
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    # Optional UI:
    path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
    path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
        # ...
]

That's all for the setup.

Now run your app.

python manage.py runserver

And open your browser http://127.0.0.1:8000/api/schema/swagger-ui/ (This is the default settings for SpeedPy template, your port can be different, please see output of the Django runserver command to see your URL). OpenAPI Swagger interface

Also you can open redoc interface: http://127.0.0.1:8000/api/schema/redoc/ OpenAPI Redoc Interface

Importing definitions into Insomnia

Insomnia is a great app for testing and trying APIs.

You can import the definitions schema by providing the schema URL http://127.0.0.1:8000/api/schema

Import OpenAPI Schema definition into Desktop App Insomnia

Import OpenAPI Schema

Click "New" if this is the first time you are importing definitions for this project Import as new

Choose "Request Collection" on the next step Request Collection

Click on your newly imported requests collection

Request Collection