弊社開発環境
弊社のエンジニアチームでは以下の開発環境が最近の主流です。
サーバーサイド: Django + DjangoRestFramework(API)
WEBクライアント: Vue.js
アプリクライアント: Flutter( + Swift)( + Kotlin)
サーバーサイドとクライアントサイドで違う人が開発する場合は多く、
そのようなときにAPI設計を共有するのって難しいですよね。
そのときにSwaggerを使ったAPI設計の共有ドキュメントを生成しています。
イメージ図(Swaggerを書くと1つのAPIでこれだけの情報が取り出せます)
どうやって書いているのか
コードからドキュメントを自動生成しています。
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
"""
↓
インストール & 設定
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教室です!