akiyoko blog

akiyoko の IT技術系ブログです

Django REST Framework で API ドキュメンテーション機能を利用する方法(DRF 3.12 最新版)

この投稿は 「Django Advent Calendar 2020 - Qiita」 8日目の記事です。


akiyoko です。
この記事では、Django REST Framework(通称「DRF」)で API スキーマを自動生成する「API ドキュメンテーション」機能を簡単に利用する方法について説明します。


f:id:akiyoko:20201208093319p:plain:w600




検証環境

  • Windows 10 Home
  • Django 3.1
  • Django REST Framework 3.12



 

はじめに

Django REST Framework には、API スキーマ(どのような URL にどのようなリクエストを送ればどのようなレスポンスが返ってくるかという API の定義を記述したもの)を出力してくれる「API ドキュメンテーション」機能が備わっています。



DRF 公式ドキュメント


API スキーマの仕様は「OpenAPI 3.0」に準拠しています。「OpenAPI 3.0」は、REST API インタフェース記述の標準化を目指して Swagger 2.0 を統合して策定された仕様です。

swagger.io


OpenAPI スキーマファイル(YAML形式)の例を次に示します。

openapi: "3.0.0"
info:
  title: Simple API overview
  version: 2.0.0
paths:
  /:
    get:
      operationId: listVersionsv2
      summary: List API versions
      responses:
        '200':
          description: |-
            200 response
          content:
            application/json:
              examples: 
                foo:
                  value:
                    {
                      "versions": [
                        {
                            "status": "CURRENT",
                            "updated": "2011-01-21T11:33:21Z",
                            "id": "v2.0",
                            "links": [
                                {
                                    "href": "http://127.0.0.1:8774/v2/",
                                    "rel": "self"
                                }
                            ]
                        },
                        {
                            "status": "EXPERIMENTAL",
                            "updated": "2013-07-23T11:33:21Z",
                            "id": "v3.0",
                            "links": [
                                {
                                    "href": "http://127.0.0.1:8774/v3/",
                                    "rel": "self"
                                }
                            ]
                        }
                      ]
                    }

...(略)...

https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v3.0/api-with-examples.yaml より引用



 

DRF 3.12 の状況

現在の最新バージョンの DRF 3.12 で OpenAPI 3.0 に準拠した API スキーマを出力する方法として、筆者は次の二つの方法を推奨します。ひとつは DRF 標準の generateschema コマンドを使って OpenAPIスキーマファイルを出力する方法、もうひとつは 「drf-spectacular」というサードパーティ製パッケージを使う方法 です。 *1



ちなみに、DRF で API スキーマを出力するにはこれまで「CoreAPI」ベースの「rest_framework.schemas.coreapi.AutoSchema」を使うのがデフォルトだったのですが、これは DRF 3.10 で非推奨になり、DRF 3.12 以降で削除予定となっています。*2
なおこの記事を書いている時点ではまだ削除はされていないようですが、今後いつ削除されるとも分かりません。

Django REST Framework v3.10 でネイティブな OpenAPI ベースのスキーマ生成が導入されたことにより、CoreAPI ベースのスキーマの使用は非推奨となりました。

Django REST Framework v3.12 で CoreAPI 関連のコードはすべて削除されます。それまでに OpenAPI スキーマに切り替えてください。

https://www.django-rest-framework.org/coreapi/ の内容を抜粋して翻訳)



本記事では、DRF 3.12 で OpenAPI 3.0 に準拠した API スキーマを出力する方法として

  • 【方法1】generateschema コマンドを使って OpenAPIスキーマファイルを出力する方法
  • 【方法2】drf-spectacular を利用する方法

について紹介します。


 

【方法1】DRF 標準の generateschema コマンドを使ってスキーマファイルを出力する

DRF 標準の generateschema コマンドを使って OpenAPI スキーマファイルを出力するには、PyYAML パッケージと uritemplate パッケージが必要です。


そこで、次のようにして PyYAML と uritemplate をそれぞれインストールします。

(venv) > pip install PyYAML==5.3.* uritemplate==3.0.*


次のように generateschema コマンドを実行すれば、OpenAPI 3.0 に対応した YAML形式のスキーマファイルを出力することができます。ちなみに format オプションで「openapi-json」を指定すれば、JSON 形式のファイルを出力することも可能です。

(venv) > python manage.py generateschema --file schema.yml


コマンドを実行すると、次のようなスキーマファイルが出力されます。

openapi: 3.0.2
info:
  title: ''
  version: ''
paths:
  /api/v0/books/:
    get:
      operationId: listBookListCreates
      description: "\u672C\u30E2\u30C7\u30EB\u306E\u53D6\u5F97\uFF08\u4E00\u89A7\uFF09\
        API\u306B\u5BFE\u5FDC\u3059\u308B\u30CF\u30F3\u30C9\u30E9\u30E1\u30BD\u30C3\
        \u30C9"
      parameters: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items: {}
          description: ''
      tags:
      - api

      ...(略)...



出力したスキーマファイルを、OpenAPI に対応した Swagger EditorSwagger Inspector などのツールに読み込ませて、ツール上で API の定義を確認したり、API クライアント(API へのリクエストを実行できるツール)として利用したりすることができます。



オンライン API ドキュメントエディタ Swagger Editor の画面例


f:id:akiyoko:20201202234527p:plain:w500


Swagger Inspector の画面例


f:id:akiyoko:20201202234559p:plain:w500


このほかにも OpenAPI スキーマファイルが利用できるツールは多数存在します。

openapi.tools


公式ドキュメント では、URLconf やテンプレートの準備をして Swagger UI と ReDoc の二種類の API ドキュメント画面を表示させる方法を紹介していますが、次に示す drf-spectacular を利用する方が簡単なので筆者はそちらを推します(公式ドキュメントでも代替案として drf-spectacular を紹介しています)。



 

【方法2】drf-spectacular を利用する

これまで DRF で標準になっていた CoreAPI ベースの「AutoSchema」を使えば、次のような API ドキュメント画面を簡単に構築することができました。*3


f:id:akiyoko:20201204000317p:plain:w450

しかし先述のように、CoreAPI ベースの「AutoSchema」の利用は非推奨になってしまいました。そこで、代わりに「drf-spectacular」を利用すれば、OpenAPI 3.0 準拠の API スキーマファイルを出力できるのに加えて、Swagger UI 形式と ReDoc 形式の二種類の API ドキュメント画面を自動生成することができます。

 

導入方法

導入方法はほぼ 公式ドキュメント に書いてある通りです。


まず、drf-spectacular をインストールします。*4

(venv) > pip install drf-spectacular==0.12.*


次に、設定ファイルの「INSTALLED_APPS」に「drf_spectacular」を追加し、「REST_FRAMEWORK」の「DEFAULT_SCHEMA_CLASS」に「drf_spectacular.openapi.AutoSchema」を設定します。


config/settings.py(設定ファイル)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # 3rd party apps
    'drf_spectacular',  # 追加

    ...
]

...

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',  # 追加
}


OpenAPI スキーマファイルを出力するだけなら設定はここまでで OK です。コマンドプロンプトから spectacular コマンドを使えば、API スキーマファイルを出力することができます。

(venv) > python manage.py spectacular --file schema.yml



APIドキュメント画面を自動生成したいのであれば、続けて URLconf に次の設定を書き加えます。ちなみに、DEBUG が False の場合にのみ APIドキュメント画面を表示できるようにしています。


config/urls.py(URLconf)

from django.urls import include, path
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView  # 追加

urlpatterns = [
    ...(略)...
]

if settings.DEBUG:
    urlpatterns += [
        path('api/schema/', SpectacularAPIView.as_view(), name='schema'),                                      # 追加
        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'),              # 追加
    ]


 

Swagger UI 形式の APIドキュメント画面

設定完了後に runserver を起動し、(起動 URL が「127.0.0.1:8000」の場合)ブラウザで「http://127.0.0.1:8000/api/schema/swagger-ui/」にアクセスすれば、Swagger UI 形式の APIドキュメント画面が表示できます。


f:id:akiyoko:20201202231159p:plain:w550


API ごとの「Try it out」ボタンをクリックして、「Parameters」を適宜入力して「Execute」ボタンをクリックすることでリクエストを送信することができるので、API クライアントとしても利用することができます。



 

ReDoc 形式の APIドキュメント画面

ReDoc 形式の APIドキュメント画面(http://127.0.0.1:8000/api/schema/redoc/)は次のようになります。


f:id:akiyoko:20201202232040p:plain:w550




 

カスタマイズ

これでよいかと思いきや、ちょっとしたカスタマイズが必要な箇所もあります。

例えば、ListAPIView や RetrieveAPIView などの汎用 APIView 系ビューや ModelViewSet 系ビューなど(クラス変数 serializer_class を指定するもの)は入出力のパラメータが自動判定されるのですが、APIView を継承しているビューではドキュメンテーションが不完全になります。その場合は、extend_schema でドキュメンテーション用の追加設定をしてあげる必要があります。


apiv0/views.py(ビュー)

from drf_spectacular.utils import extend_schema
from rest_framework import status, views
from rest_framework.response import Response

from shop.models import Book
from .serializers import BookSerializer


class BookListCreateAPIView(views.APIView):
    """本モデルの取得(一覧)・登録APIクラス"""

    @extend_schema(
        responses={200: BookSerializer},
    )
    def get(self, request, *args, **kwargs):
        """本モデルの取得(一覧)APIに対応するハンドラメソッド"""

        ...(略)...

        return Response(serializer.data, status.HTTP_200_OK)

    @extend_schema(
        request=BookSerializer,
        responses={201: BookSerializer},
    )
    def post(self, request, *args, **kwargs):
        """本モデルの登録APIに対応するハンドラメソッド"""

        ...(略)...

        return Response(serializer.data, status.HTTP_201_CREATED)


他にもいろいろ追加設定ができますが、詳細については公式ドキュメントを参照してください。

Settings — drf-spectacular documentation





 

まとめ

Django REST Framework(DRF)にはデフォルトで OpenAPI 3.0 に対応した API スキーマを出力してくれる「API ドキュメンテーション」機能が備わっています。利用方法は簡単で、generateschema コマンドでスキーマファイルを出力するだけです(ただし、PyYAML と uritemplate のインストールが必要)。


API スキーマをリアルタイムに反映した API ドキュメント画面を表示したいのであれば、drf-spectacular パッケージを利用するのが簡単です。なお、DRF 3.12 以降は、DRF 3.10 までで標準だった CoreAPI ベースの APIドキュメント画面が利用できなくなるので注意が必要です。



 

宣伝

Django の技術同人誌をこれまでに4冊出しました。開発のお供にどうぞ。



現場で使える Django の教科書《基礎編》

「現場で使える Django の教科書」シリーズ第1弾となる Django の技術同人誌。Django を現場で使うための基礎知識やベストプラクティスについて、初心者・初級者向けに解説した本です。B5・本文180ページ。


★ Amazon(電子版/ペーパー版)


★ BOOTH(ペーパー版)



現場で使える Django の教科書《実践編》

《基礎編》の続編にあたる「現場で使える Django の教科書」シリーズの第2弾。認証まわり、ファイルアップロード、ユニットテスト、デプロイ、セキュリティ、高速化など、さらに実践的な内容に踏み込んでいます。現場で Django を本格的に活用したい、あるいはすでに活用している方にピッタリの一冊。B5・本文180ページ。


★ Amazon(電子版)


★ BOOTH(ペーパー版)



現場で使える Django REST Framework の教科書

Django で REST API を構築する際の鉄板ライブラリである「Django REST Framework」(通称「DRF」)にフォーカスした、「現場で使える Django の教科書」シリーズの第3弾。B5・本文204ページ。


★ Amazon(電子版)


★ BOOTH(ペーパー版)



現場で使える Django 管理サイトのつくり方

Django の管理サイト(Django Admin)だけに特化した、ニッチでオンリーワンな一冊。管理サイトをカスタマイズする前に絶対に読んでほしい本です。B5・本文152ページ。


★ Amazon(電子版)


★ BOOTH(ペーパー版)

*1:サードパーティ製パッケージとしては「drf-yasg」も有名ですが、README にも書かれている通り、OpenAPI 3.0 には当分対応しないとのことなので検討を除外しています。

*2:DRF 3.10 以降はデフォルトで OpenAPI ベースの「rest_framework.schemas.openapi.AutoSchema」を使う設定になっているので、追加設定は特に必要ありません。

*3:https://www.django-rest-framework.org/coreapi/

*4:依存パッケージの PyYAML と uritemplate もインストールされます。