Documenting your API

A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state.

— Roy Fielding, REST APIs must be hypertext driven

REST框架提供对API文档的内置支持。 还有一些很棒的第三方文档工具可用。

Built-in API documentation

内置的API文档包括:

  • Documentation of API endpoints.
  • 为每个可用的API客户端库自动生成代码示例。
  • Support for API interaction.

Installation

需要coreapi库作为API文档的依赖性。 确保安装最新版本。 pygmentsmarkdown库是可选的,但建议使用。

要安装API文档,您需要将其包含在项目URLconf中:

from rest_framework.documentation import include_docs_urls

urlpatterns = [
    ...
    url(r'^docs/', include_docs_urls(title='My API title'))
]

这将包括两个不同的视图:

  • /docs/ - The documentation page itself.
  • /docs/schema.js - A JavaScript resource that exposes the API schema.

注意:默认情况下,include_docs_urls配置基础SchemaView以生成public模式。 这意味着视图不会使用request实例进行实例化。 i.e. 在视图内self.request将是None

To be compatible with this behaviour methods (such as get_serializer or get_serializer_class etc.) which inspect self.request or, particularly, self.request.user may need to be adjusted to handle this case.

You may ensure views are given a request instance by calling include_docs_urls with public=False:

from rest_framework.documentation import include_docs_urls

urlpatterns = [
    ...
    # Generate schema with valid `request` instance:
    url(r'^docs/', include_docs_urls(title='My API title', public=False))
]

Documenting your views

You can document your views by including docstrings that describe each of the available actions. For example:

class UserList(generics.ListAPIView):
    """
    Return a list of all the existing users.
    """

If a view supports multiple methods, you should split your documentation using method: style delimiters.

class UserList(generics.ListCreateAPIView):
    """
    get:
    Return a list of all the existing users.

    post:
    Create a new user instance.
    """

When using viewsets, you should use the relevant action names as delimiters.

class UserViewSet(viewsets.ModelViewSet):
    """
    retrieve:
    Return the given user.

    list:
    Return a list of all the existing users.

    create:
    Create a new user instance.
    """

documentation API Reference

The rest_framework.documentation module provides three helper functions to help configure the interactive API documentation, include_docs_urls (usage shown above), get_docs_view and get_schemajs_view.

include_docs_urls employs get_docs_view and get_schemajs_view to generate the url patterns for the documentation page and JavaScript resource that exposes the API schema respectively. They expose the following options for customisation. (get_docs_view and get_schemajs_view ultimately call rest_frameworks.schemas.get_schema_view(), see the Schemas docs for more options there.)

include_docs_urls

  • title: Default None. May be used to provide a descriptive title for the schema definition.
  • description: Default None. May be used to provide a description for the schema definition.
  • schema_url: Default None. May be used to pass a canonical base URL for the schema.
  • public: Default True. Should the schema be considered public? If True schema is generated without a request instance being passed to views.
  • patterns: Default None. A list of URLs to inspect when generating the schema. If None project's URL conf will be used.
  • generator_class: Default rest_framework.schemas.SchemaGenerator. May be used to specify a SchemaGenerator subclass to be passed to the SchemaView.
  • authentication_classes: Default api_settings.DEFAULT_AUTHENTICATION_CLASSES. May be used to pass custom authentication classes to the SchemaView.
  • permission_classes: Default api_settings.DEFAULT_PERMISSION_CLASSES May be used to pass custom permission classes to the SchemaView.
  • renderer_classes: Default None. May be used to pass custom renderer classes to the SchemaView.

get_docs_view

  • title: Default None. May be used to provide a descriptive title for the schema definition.
  • description: Default None. May be used to provide a description for the schema definition.
  • schema_url: Default None. May be used to pass a canonical base URL for the schema.
  • public: Default True. If True schema is generated without a request instance being passed to views.
  • patterns: Default None. A list of URLs to inspect when generating the schema. If None project's URL conf will be used.
  • generator_class: Default rest_framework.schemas.SchemaGenerator. May be used to specify a SchemaGenerator subclass to be passed to the SchemaView.
  • authentication_classes: Default api_settings.DEFAULT_AUTHENTICATION_CLASSES. May be used to pass custom authentication classes to the SchemaView.
  • permission_classes: Default api_settings.DEFAULT_PERMISSION_CLASSES. May be used to pass custom permission classes to the SchemaView.
  • renderer_classes: Default None. May be used to pass custom renderer classes to the SchemaView. If None the SchemaView will be configured with DocumentationRenderer and CoreJSONRenderer renderers, corresponding to the (default) html and corejson formats.

get_schemajs_view

  • title: Default None. May be used to provide a descriptive title for the schema definition.
  • description: Default None. May be used to provide a description for the schema definition.
  • schema_url: Default None. May be used to pass a canonical base URL for the schema.
  • public: Default True. If True schema is generated without a request instance being passed to views.
  • patterns: Default None. A list of URLs to inspect when generating the schema. If None project's URL conf will be used.
  • generator_class: Default rest_framework.schemas.SchemaGenerator. May be used to specify a SchemaGenerator subclass to be passed to the SchemaView.
  • authentication_classes: Default api_settings.DEFAULT_AUTHENTICATION_CLASSES. May be used to pass custom authentication classes to the SchemaView.
  • permission_classes: Default api_settings.DEFAULT_PERMISSION_CLASSES May be used to pass custom permission classes to the SchemaView.

Customising code samples

The built-in API documentation includes automatically generated code samples for each of the available API client libraries.

You may customise these samples by subclassing DocumentationRenderer, setting languages to the list of languages you wish to support:

from rest_framework.renderers import DocumentationRenderer


class CustomRenderer(DocumentationRenderer):
    languages = ['ruby', 'go']

For each language you need to provide an intro template, detailing installation instructions and such, plus a generic template for making API requests, that can be filled with individual request details. See the templates for the bundled languages for examples.


Third party packages

There are a number of mature third-party packages for providing API documentation.

drf-yasg - Yet Another Swagger Generator

drf-yasg is a Swagger generation tool implemented without using the schema generation provided by Django Rest Framework.

It aims to implement as much of the OpenAPI specification as possible - nested schemas, named models, response bodies, enum/pattern/min/max validators, form parameters, etc. - and to generate documents usable with code generation tools like swagger-codegen.

This also translates into a very useful interactive documentation viewer in the form of swagger-ui:

Screenshot - drf-yasg

DRF OpenAPI

DRF OpenAPI bridges the gap between OpenAPI specification and tool chain with the schema exposed out-of-the-box by Django Rest Framework. Its goals are:

  • To be dropped into any existing DRF project without any code change necessary.
  • Provide clear disctinction between request schema and response schema.
  • Provide a versioning mechanism for each schema. Support defining schema by version range syntax, e.g. >1.0, <=2.0
  • Support multiple response codes, not just 200
  • All this information should be bound to view methods, not view classes.

It also tries to stay current with the maturing schema generation mechanism provided by DRF.

Screenshot - DRF OpenAPI


DRF Docs

DRF Docs allows you to document Web APIs made with Django REST Framework and it is authored by Emmanouil Konstantinidis. It's made to work out of the box and its setup should not take more than a couple of minutes. Complete documentation can be found on the website while there is also a demo available for people to see what it looks like. Live API Endpoints allow you to utilize the endpoints from within the documentation in a neat way.

Features include customizing the template with your branding, settings for hiding the docs depending on the environment and more.

Both this package and Django REST Swagger are fully documented, well supported, and come highly recommended.

Screenshot - DRF docs


Django REST Swagger

Marc Gibbons的Django REST Swagger将REST框架与Swagger API文档工具集成在一起。 该软件包提供了介绍清楚的API文档,并包括用于测试API端点的交互式工具。

Django REST Swagger支持REST框架2.3及更高版本。

Mark还是REST Framework Docs软件包的作者,该软件包为您的API提供了干净,简单的自动生成的文档,但已过时,已移至Django REST Swagger。

该软件包和DRF文档均已得到充分记录,受到良好支持,并强烈建议使用。

Screenshot - Django REST Swagger


DRF AutoDocs

Oleksander Mashianovs的DRF Auto Docs自动api渲染器。

毫不费力地收集您几乎所有写入文档的代码。

Supports:

  • functional view docs
  • tree-like structure
  • Docstrings:
  • markdown
  • preserve space & newlines
  • formatting with nice syntax
  • Fields:
  • choices rendering
  • help_text (to specify SerializerMethodField output, etc)
  • smart read_only/required rendering
  • Endpoint properties:
  • filter_backends
  • authentication_classes
  • permission_classes
  • extra url params(GET params)

whole structure


Apiary

还有其他各种在线工具和服务可用于提供API文档。 一种值得注意的服务是Apiary 使用Apiary,您可以使用类似于markdown的简单语法来描述您的API。 生成的文档包括API交互,用于测试的模拟服务器

Screenshot - Apiary


Self describing APIs

REST框架提供的可浏览API使您的API完全可以自我描述。 只需访问浏览器中的URL,即可提供每个API端点的文档。

Screenshot - Self describing API


Setting the title

The title that is used in the browsable API is generated from the view class name or function name. Any trailing View or ViewSet suffix is stripped, and the string is whitespace separated on uppercase/lowercase boundaries or underscores.

For example, the view UserListView, will be named User List when presented in the browsable API.

When working with viewsets, an appropriate suffix is appended to each generated view. For example, the view set UserViewSet will generate views named User List and User Instance.

Setting the description

The description in the browsable API is generated from the docstring of the view or viewset.

If the python markdown library is installed, then markdown syntax may be used in the docstring, and will be converted to HTML in the browsable API. For example:

class AccountListView(views.APIView):
    """
    Returns a list of all **active** accounts in the system.

    For more details on how accounts are activated please [see here][ref].

    [ref]: http://example.com/activating-accounts
    """

Note that when using viewsets the basic docstring is used for all generated views. To provide descriptions for each view, such as for the the list and retrieve views, use docstring sections as described in Schemas as documentation: Examples.

The OPTIONS method

REST framework APIs also support programmatically accessible descriptions, using the OPTIONS HTTP method. A view will respond to an OPTIONS request with metadata including the name, description, and the various media types it accepts and responds with.

When using the generic views, any OPTIONS requests will additionally respond with metadata regarding any POST or PUT actions available, describing which fields are on the serializer.

You can modify the response behavior to OPTIONS requests by overriding the options view method and/or by providing a custom Metadata class. For example:

def options(self, request, *args, **kwargs):
    """
    Don't include the view description in OPTIONS responses.
    """
    meta = self.metadata_class()
    data = meta.determine_metadata(request, self)
    data.pop('description')
    return data

See the Metadata docs for more details.


The hypermedia approach

为了完全RESTful,API应该在其发送的响应中将其可用的操作显示为超媒体控件。

采用这种方法,而不是预先记录可用的API端点,而是将说明集中在使用的媒体类型上。 在任何给定的URL上可能执行的可用操作均未严格固定,而是通过返回的文档中存在链接和表单控件来使其可用。

要实现超媒体API,您需要为API确定合适的媒体类型,并为该媒体类型实现自定义渲染器和解析器。 The REST, Hypermedia & HATEOAS section of the documentation includes pointers to background reading, as well as links to various hypermedia formats.