API のドキュメント化

REST API は、リソースの表現とアプリケーション状態の駆動に使用されるメディアタイプ(複数可)の定義に、その記述努力のほとんどを費やすべきです。

— Roy Fielding, REST APIs must be hypertext driven

REST framework は、API を文書化するさまざまな選択肢を提供しています。以下は、最も人気のあるものの網羅的ではないリストです。

OpenAPI サポートのためのサードパーティパッケージ

drf-spectacular

drf-spectacular は、拡張性、カスタマイズ性、クライアント生成に重点を置いた OpenAPI 3 スキーマ生成ライブラリです。OpenAPI スキーマの生成と提示には、これが推奨される方法です。

このライブラリは、可能な限り多くのスキーマ情報を抽出しながら、容易なカスタマイズのためのデコレータと拡張機能を提供することを目指しています。swagger-codegenSwaggerUIRedoc、i18n、バージョン管理、認証、ポリモーフィズム(動的なリクエストとレスポンス)、クエリ/パス/ヘッダーパラメータ、ドキュメントなどに対する明示的なサポートがあります。DRF のいくつかの一般的なプラグインもすぐに利用できます。

drf-yasg

drf-yasg は、Django Rest Framework が提供するスキーマ生成を使用せずに実装された Swagger / OpenAPI 2 生成ツールです。

これは、OpenAPI 2 仕様の可能な限り多くの部分(ネストされたスキーマ、名前付きモデル、レスポンスボディ、enum/pattern/min/max バリデータ、フォームパラメータなど)を実装し、`swagger-codegen` などのコード生成ツールで使用できるドキュメントを生成することを目的としています。

これは、`swagger-ui` の形で非常に便利な対話型のドキュメントビューアにも変換されます。

Screenshot - drf-yasg


組み込みの OpenAPI スキーマ生成 (非推奨)

非推奨に関する注意:OpenAPI スキーマを生成するための REST framework の組み込みサポートは、代わりにこの機能を提供できるサードパーティパッケージに置き換えられました。代替として、drf-spectacular パッケージの使用をお勧めします。

OpenAPI スキーマから HTML ドキュメントページを生成できるパッケージが多数あります。

2 つの一般的なオプションは、Swagger UIReDoc です。

どちらも、静的なスキーマファイルの場所か動的な `SchemaView` エンドポイントを指定するだけで済みます。

Swagger UI を使用した最小限の例

スキーマのドキュメントの例に従って動的な `SchemaView` をルーティングしたと仮定すると、Swagger UI を使用するための最小限の Django テンプレートは次のようになります。

<!DOCTYPE html>
<html>
  <head>
    <title>Swagger</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="//unpkg.com/swagger-ui-dist@3/swagger-ui.css" />
  </head>
  <body>
    <div id="swagger-ui"></div>
    <script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
    <script>
    const ui = SwaggerUIBundle({
        url: "{% url schema_url %}",
        dom_id: '#swagger-ui',
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIBundle.SwaggerUIStandalonePreset
        ],
        layout: "BaseLayout",
        requestInterceptor: (request) => {
          request.headers['X-CSRFToken'] = "{{ csrf_token }}"
          return request;
        }
      })
    </script>
  </body>
</html>

これをテンプレートフォルダに `swagger-ui.html` として保存します。次に、プロジェクトの URL 設定で `TemplateView` をルーティングします。

from django.views.generic import TemplateView

urlpatterns = [
    # ...
    # Route TemplateView to serve Swagger UI template.
    #   * Provide `extra_context` with view name of `SchemaView`.
    path(
        "swagger-ui/",
        TemplateView.as_view(
            template_name="swagger-ui.html",
            extra_context={"schema_url": "openapi-schema"},
        ),
        name="swagger-ui",
    ),
]

高度な使用方法については、Swagger UI ドキュメント を参照してください。

ReDoc を使用した最小限の例。

スキーマのドキュメントの例に従って動的な `SchemaView` をルーティングしたと仮定すると、ReDoc を使用するための最小限の Django テンプレートは次のようになります。

<!DOCTYPE html>
<html>
  <head>
    <title>ReDoc</title>
    <!-- needed for adaptive design -->
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
    <!-- ReDoc doesn't change outer page styles -->
    <style>
      body {
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <redoc spec-url='{% url schema_url %}'></redoc>
    <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
  </body>
</html>

これをテンプレートフォルダに `redoc.html` として保存します。次に、プロジェクトの URL 設定で `TemplateView` をルーティングします。

from django.views.generic import TemplateView

urlpatterns = [
    # ...
    # Route TemplateView to serve the ReDoc template.
    #   * Provide `extra_context` with view name of `SchemaView`.
    path(
        "redoc/",
        TemplateView.as_view(
            template_name="redoc.html", extra_context={"schema_url": "openapi-schema"}
        ),
        name="redoc",
    ),
]

高度な使用方法については、ReDoc ドキュメント を参照してください。

自己記述型 API

REST framework が提供するブラウザブル API を使用すると、API を完全に自己記述的にすることができます。各 API エンドポイントのドキュメントは、ブラウザで URL にアクセスするだけで提供できます。

Screenshot - Self describing API


タイトルの設定

ブラウザブル API で使用されるタイトルは、ビューのクラス名または関数名から生成されます。末尾の `View` または `ViewSet` サフィックスは削除され、文字列は大文字/小文字の境界またはアンダースコアで空白区切りされます。

たとえば、ビュー `UserListView` は、ブラウザブル API に表示されるときに `User List` という名前になります。

Viewsets を使用する場合、適切なサフィックスが各生成されたビューに追加されます。たとえば、ViewSet `UserViewSet` は、`User List` と `User Instance` という名前のビューを生成します。

説明の設定

ブラウザブル API の説明は、ビューまたは viewset の docstring から生成されます。

Python の `Markdown` ライブラリがインストールされている場合、Markdown 構文 を docstring で使用でき、ブラウザブル API で HTML に変換されます。例:

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
    """

Viewsets を使用する場合、基本的な docstring は生成されたすべてのビューに使用されることに注意してください。リストビューや取得ビューなど、各ビューの説明を提供するには、スキーマとしてのドキュメント:例 で説明されているように、docstring セクションを使用してください。

OPTIONS メソッド

REST framework API は、OPTIONS HTTP メソッドを使用して、プログラムからアクセスできる説明もサポートしています。ビューは、OPTIONS リクエストに、名前、説明、および受け入れるおよび応答するさまざまなメディアタイプを含むメタデータで応答します。

ジェネリックビューを使用する場合、すべての `OPTIONS` リクエストは、使用可能な `POST` または `PUT` アクションに関するメタデータ(シリアライザーにあるフィールドの説明を含む)にも追加で応答します。

`options` ビューメソッドをオーバーライドするか、カスタムメタデータクラスを提供することで、`OPTIONS` リクエストに対する応答の動作を変更できます。例:

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 Response(data=data, status=status.HTTP_200_OK)

メタデータのドキュメント を参照して詳細を確認してください。


ハイパーメディアアプローチ

完全に RESTful であるためには、API は利用可能なアクションを、送信するレスポンス内のハイパーメディアコントロールとして提示する必要があります。

このアプローチでは、利用可能な API エンドポイントを事前に文書化するのではなく、代わりに使用されるメディアタイプに重点を置いて説明します。特定の URL で実行できるアクションは厳密に固定されていませんが、返されたドキュメント内のリンクとフォームコントロールの存在によって提供されます。

ハイパーメディア API を実装するには、API に適したメディアタイプを選択し、そのメディアタイプに対してカスタムレンダラーとパーサーを実装する必要があります。ドキュメントの REST、ハイパーメディア & HATEOAS セクションには、背景資料へのポインタと、さまざまなハイパーメディア形式へのリンクが含まれています。