Help us understand the problem. What is going on with this article?

DjangoRestFrameworkのコードからSwaggerドキュメントを生成しAPI設計を共有

弊社開発環境

弊社のエンジニアチームでは以下の開発環境が最近の主流です。

サーバーサイド: Django + DjangoRestFramework(API)
WEBクライアント: Vue.js
アプリクライアント: Flutter( + Swift)( + Kotlin)

サーバーサイドとクライアントサイドで違う人が開発する場合は多く、
そのようなときにAPI設計を共有するのって難しいですよね。
そのときにSwaggerを使ったAPI設計の共有ドキュメントを生成しています。

イメージ図(Swaggerを書くと1つのAPIでこれだけの情報が取り出せます)

スクリーンショット_2019-12-06_21_29_21.png

どうやって書いているのか

コードからドキュメントを自動生成しています。

class AbcApiView(ApiView):
    @swagger_auto_schema(
        request_body=AbcRequestSerializer,
        responses={200: openapi.Response('OK', AbcResponseSerializer)})
    def post(self, request, *args, **kwargs):
        """
        期間限定キャンペーンで無料になっている商品を一覧表示
        """
        pass

DRFでSerializerを作っている人は、request_bodyとresponsesにSerializerの型を渡すだけ😍
これだけでドキュメントを生成してくれます。
ドキュメントを追加するのに3行のコードと1行の説明文(docstring)だけで済みます!!

ついでにSerializerも貼っておきます。

class AbcRequestSerializer(serializers.Serializer):
    page = serializers.IntegerField(default=1)
    genre = serializers.CharField(default='', allow_blank=True, allow_null=True)

class AbcApiResponseSerializer(serializers.Serializer):
    items = serializers.ListField(child=ZyxSerializer(), default=[])
    page = serializers.IntegerField()
    has_next = serializers.BooleanField()
    has_prev = serializers.BooleanField()
    max_page = serializers.IntegerField()

シリアライザーにフィールドを追加したいとき、ドキュメントをメンテしなくて済むのでラクチンですね。

yamlでも書ける

yamlで書いてみると以下のようになります。

paths:
  /api/campaign/v1/:
    post:
      summary: 期間限定キャンペーンで無料になっている商品を一覧表示
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                page:
                  type: integer
                genre:
                  type: string
                  default: ""
              example:   # Sample object
                page: 2
                name: "MANGA"
      responses:
        '200':
          description: OK

長い!!!! ( responseを書くのを諦めた

設計段階の場合はこれでいいのですが、たくさんのエンドポイントを作っているとファイルが1000行くらいすぐに増えます。またメンテもしなくなるので、古いドキュメントが完成です。

docstringの部分には、もうちょっと複雑なことも書ける

docstringの部分には、htmlやコードも書けます。

class AbcApiView(ApiView):
    def post(self, request, *args, **kwargs):
    """
    まとめ買いのリスト表示を行います。

    :param tcode: 基準となるコードを入力します。

    :return 200 ok_response

    ```
    [{
        title_code: 'tcode1', // タイトルコードが一意でない場合がある。シリーズもの。
        serial_number: 1 // tcodeとserial_numberの2つで一意
        price: 0, // 購入するための金額
        is_purchased: false, // 購入済みの場合はグレーアウト
        is_selected: false, // 購入対象をユーザーが選択
        regular_price: 100, // 通常価格
        campaign_text: 'campaign' // 無料・半額キャンペーン情報
        thumbnail_image_path: '/favicon/favicon256.png' // サムネイル
    },]
    ```
    priceとregular_priceは違うものになります。<br>
    regular_priceは通常価格。<br>
    500円のものを途中まで購入している場合は、priceは300
    """

スクリーンショット_2019-12-06_21_40_44.png

インストール & 設定

https://github.com/axnsan12/drf-yasg
に従ってインストールすればすぐに使えました😁

一点だけ変更したところを記載します。

schema_view = get_schema_view(
    ....
    permission_classes=(permissions.AllowAny,) if settings.DEBUG else (permissions.IsAdminUser,),
)

permission_classesは閲覧権限です。
ローカルではログインしていなくても閲覧できますが、ローカル以外では管理者権限でないと閲覧できないようにしました。

以上です。
明日は弊社CTOの@ytyng先生のDjangoAdmin教室です!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした