Django REST Framework and YASG

This post explores the best practices and packages used to provide a Swagger/OpenAPI specification for an API implemented using Django REST Framework. Using Django and Django REST Framework is an excellent way to maintain a RESTful API over an Relational Database (RDBMS). Just like Django itself, it has a rich ecosystem of add-on packages. However, maintainng an OpenAPI schema specification is not an out-of-the box feature.

But why provide a Swagger/OpenAPI schema specification at all? Not all APIs need to be designed by contract, but all APIs need testing, documentation, and security. A Swagger aka OpenAPI specification is a JSON or YAML document that can tell tools how to call your API. These include API manager and gateway applications, security and other testing tools, and documentation generators/browsers. All of these tools need to know the URLs, e.g. endpoints, for the API, what HTTP methods will be supported for each URL, what parameters may be provided, and what the response format will look like.

If an API is designed by contract, the OpenAPI specification could be a hand-crafted document, maybe written using the Swagger Editor, exported to a git repository, and then served as either JSON or YAML. However, even if this is the case, we have two problems:

So, having an API specification that is generated from our actual implementation is by far the best solution. This is exactly what the designers of the Simple Object Access Protocol (SOAP) discovered, and most Web Services Description Language (WSDL) documents are written by the API application framework.

Suppose I’ve just convinced your boss, and he/she insists that the new API must have an OpenAPI specification. You google it, and discover that OpenAPI 2 and Swagger 2 are the same specification, and the latest version is OpenAPI 3. OpenAPI 3 fixes problems; the API endpoints for each environment can now be placed in one document, and the schema can express more polymorphic responses. This sounds great, but we want our API tools to work with our API tools.

Some examples include:

SoapUI Ng Pro is made by SmartBear Software, and since they are also the makers of that swagger editor I linked above, they are pushing version 3 hard.

However, Amazon API Gateway is probably the best API Gateway product for us. We can pay as we go, and we don’t have to manage any installation or additional acquisitiomns to use it. Amazon API Gateway only suppors OpenAPI 2. Besides, choosing a dynamically generated API specification should mean it is easy to change as the standard itself evolves.

There are a number of packages for Django that purport to generate an OpenAPI Specification. I looked at most of them, and decided that drf-yasg is the best. Let’s unpack that package name so we can remember it - “drf-yasg” is short for “Django REST Framework - Yet Another Schema Generator”. DRF is a common acronym for “Django REST Framework”, and “yasg” can be understood by remembering that the compiler tool “yacc” is an acronym for “Yet Another Compiler Compiler”.

drf-yasg has the following advantages over some of the others:

So, how do we do it?

django-rest-framework==
drf-yasg==
ruamel.yaml==
INSTALLED_APPS = (
	...
	'rest_framework',
	'drf_yasg',
)
from drf_yasg import openapi

info = openapi.Info(
    title="Snippets API",
    default_version='v1',
    description="Test description",
    terms_of_service="https://www.google.com/policies/terms/",
    contact=openapi.Contact(email="contact@snippets.local"),
    license=openapi.License(name="BSD License"),
),
from drf_yasg.views import get_schema_view

...