Customised API Documentation for Django Rest Framework Projects using drf-yasg.

Arjun Singh Yadav
4 min readSep 2, 2018

--

I have been working on a REST API project recently. Since I was familiar with Django I decided to use Django Rest Framework (DRF) for this project. Similar to Django, DRF also follows the batteries included approach where it includes the model serializers, generic views, authentication, permissions as well as automatic documentation generation (using coreapi) for the api endpoints you build.

Though the current coreapi documentation provided by DRF is good, it did not fit my needs. The following were the major issues I faced:

  1. No support to include code samples: I wanted to include cURL (and maybe Python, Ruby and JavaScript) samples to access my API endpoints through simple copy paste. Unfortunately, I didn’t find anything with the current tools to do this.
  2. Same request/query parameters for all methods: Some of the API endpoints in my project were not directly bound with django models, so I required a way to give custom request/query parameters. But I also wanted to have different methods accept different parameters or request body.

The end result which I wanted was something like this.

Example API documentation

After searching for more options, I decided on using drf-yasg (drf-yet another swagger generator). drf-yasg generates a swagger OpenAPI schema for your API containing all the views which are DRF API Views. It also provides many hooks to customise the generation of this schema. drf-yasg also contains the Redoc UI, which was exactly what I needed.

Let us now look at the two customisation approaches to cover the above mentioned issues.

1. Using swagger_auto_schema decorator

Most of the customisation which I did was through swagger_auto_schema decorator provided in utils module of drf-yasg. The parameters passed to this decorator take precedence over the auto generated schema.

Decorate your function based API views or methods in class based API views to modify the OpenAPI schema which is generated. The usage is documented at https://drf-yasg.readthedocs.io/en/latest/custom_spec.html#the-swagger-auto-schema-decorator

I am going to talk about the major parameters this decorator accepts and how they affect the generated OpenAPI schema.

  • method: For multi-method views, the method to which these options will apply to. This parameter accepts string values such as 'get' and 'post'.
  • methods: Same as methods but is a list of string. This parameter is not to be used with ‘method’ parameter.
  • auto_schema: This parameter can be used to provide a custom inspector (SwaggerAutoSchema subclass) for the views. I will talk about the custom inspector in next section.
  • request_body: This should be rest_framework Serializer class/object. The drf-yasg inspector will automatically generate the fields from the serializer fields. This parameter should not be used in case the method you are modifying is GET.
  • query_serializer: This should also be a rest_framework Serializer class/object. This will generate the schema for the accepted query parameters.
  • manual_parameters: This parameter can be used when you don’t want the parameters to be automatically generated. A list of openapi Parameter objects should be passed.
  • operation_id: This parameter will be used as the title of particular API endpoint and should be unique across the whole API.
  • operation_description: Passing this parameter will override your endpoint description collected form the doc string.
  • responses: This should be a dictionary containing all the possible responses as keys and the response body as values. The values could be either str, Serializer, Response, Schema or SchemaRef (openapi module defines Schema, SchemaRef, Parameter, Operation etc classes).
  • security: This parameter is used to specify which authentication mechanism is required to call the API endpoint. An empty list marks the endpoint as unauthenticated (i.e. removes all accepted authentication schemes), and None will inherit the top-level security requirements.

Using these we can customise most of the aspects of the endpoint documentation.

2. Using custom SwaggerAutoSchema subclass

The need for code samples was still not fulfilled after using the swagger_auto_schema decorator. The solution for this was to use a custom SwaggerAutoSchema subclass. The extra settings to incude vendor extensions (x-code-samples in our case) can be added in our custom class. Let us look at a simplified version of the code samples SwaggerAutoSchema class.

The main concept here is to update the operation object returned by the super class (which is SwaggerAutoSchema) with the plugins which we want to add. Like the x-code-samples the other x-* vendor extensions can be added. I am using django templates here to generate the code for curl and python.

In class based views, the swagger_schema class property can be set to the custom SwaggerAutoSchema class so as to use it for every method of the view. If swagger_schema is set to None the view will not be include in the schema generation (hence, not appearing in the doc).

By using and combining these two approaches, I was able to get the desired API documentation for my little project.

Thank You! Edits, suggestions and questions are welcome.

Reach me out at @arjunsinghy96 on Twitter.

--

--