まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:yaml

Swagger を使うことで、インタラクティブに実行可能な REST API のドキュメントを作ることができます。比較的有名な所では Swagger がライブデモとして用意している「ペットストア・サービスの REST API」があります:
https://petstore.swagger.io/

2020012201



↑架空の「ペットストア・ウェブサービス」が存在している前提で、ペットやその画像を登録/更新したり、検索したり、、加えてペットストア自体の登録/管理をしたり、利用者となるユーザーの管理といったペットストア運営に必要と思われる最低限の機能の REST API が実行可能な状態で公開されています。


アプリケーションを REST API ベースで作る際に、このような Swagger による API ドキュメントを用意しておくと、REST API の仕様が確認できるだけでなく、実際にパラメータを指定した上で実行したり、実行した時のデータのやりとりやその結果までを確認することができて便利です。REST API を作成した時にセットで作っておくと、開発後の運用時や機能追加、引き継ぎといった段階においても非常に役立つインタラクティブドキュメントだと思っています。


この Swagger ドキュメントは REST API 開発後に swagger.yaml (または swagger.json)というファイルを用意することで自動作成が可能になります。特定のルールに基づいて REST API の内容(ホスト、パス、メソッド、パラメータ、返り値、・・)を記述していくと、ドキュメントの UI は自動的に作成され、指定した通りに実行が可能になります(そして実際に実行された結果を確認することもできるようになります)。

なお上述のペットストア・サービス REST API の定義内容はこちらの Swagger Editor で確認できます:
https://editor.swagger.io/

2020012205


swagger.yaml の記述方法そのものについては本ブログエントリの範囲ではないので、興味ある方は別途調べていただきたいのですが、そこまで難しい内容ではないと感じています。例えば GET /users?limit=xx&offset=yy といった具合に2つの URL パラメータ(limit, offset)を指定可能(必須ではない)な GET の REST API が存在していて、これを Swagger ドキュメントに記述する場合は swagger.yaml ファイルに以下のように指定します:
  :
/users
  get
    parameters:
      - name: limit
        type: number
        in: query
        description: 取得するデータ数
      - name: offset
        type: number
        in: query
        description: 取得するデータのオフセット
  :

実際に Swagger ドキュメントとして生成すると、この部分は以下のような UI に変換されて指定可能になる、といった具合です:
2020012202



で、ここからが本エントリの本題です。この Swagger ドキュメント(の yaml ファイル)を記述する際の、特に「ファイルアップロード」の API を記述する場合のパラメータ指定方法が特殊でちとわかりにくいものでした。試行錯誤した上で実際に動く例を見つけたので、自分の備忘録も兼ねて以下に紹介します。

まず API そのものは単純なファイルアップロード(POST /file)と仮定します。受け取るパラメータはアップロードするファイル本体だけ、他のパラメータは(Swagger ドキュメント的には特別な部分ではないので)いったん無視します。Node.js + Express 環境であれば、以下のような内容で作られているようなものです:
//. multer モジュールを利用してアップロードファイルを受け取る
var express = require( 'express' ),
    multer = require( 'multer' ),
    router = express.Router(),

    :

//. multer モジュールの設定
router.use( multer( { dest: './tmp/' } ).single( 'file' ) );

    :

//. POST /file として REST API を用意する
router.post( '/file', function( req, res ){
  //. アップロードされたファイルの情報を取り出す
  var filepath = req.file.path;
  var filetype = req.file.mimetype;

    :
    :


UI 側からこの API を呼ぶ時は、普通に以下の様な enctype="multipart/form-data" を指定した form の HTML を用意すれば実行できるものです:
<form method="POST" action="/file" enctype="multipart/form-data">
<input type="file" name="file"/>
</form>

↓こんな感じの見た目になって実行されるものです:
2020012203

このような挙動を行う API : POST /file を Swagger ドキュメントとして用意する場合の(パラメータ部分の)記述方法をどのようにするか、というのが今回のテーマでした。

ちょっと特殊な指定方法となりますが、結論としては以下のようになります:
  :
/file:
  post:
    consumes:
      - multipart/form-data
    parameters:
      - in: formData
        name: file
        type: file
        description: アップロードするファイル
        required: true
  :

特殊な部分を解説します。まず HTML の form 属性で enctype="multipart/form-data" 指定を行っていた部分ですが、上述のように consumes: で "multipart/form-data" を指定することで実現します。

またパラメータ部分ですが、POST のデータとして送信するので "in: formData" を指定します。またパラメータの種類として "type: file" も付与します。 加えて、このパラメータは API 実行時には必須指定パラメータとなるので "required: true" も付与します。swagger.yaml ではこのように指定することでファイルアップロード系の API を記述できます。

参考程度に、このように指定した swatter.yaml を実際に Swagger ドキュメントに変換して表示すると、以下のような画面になりました:
2020012204


期待通りの結果になりました。

Swagger APIはインタラクティブに動く REST API のドキュメントを比較的簡単に作ることができて便利です。自分も実際に業務やプライベートアプリに使っています。

この機能を使う場合、YAML と言われるフォーマットをベースにした記述方法で API の仕様を記述するだけで動く API ドキュメントページを作ることができます。

で、この YAML で仕様を記述する際に「コメント」を記述したくなることがあります。実質的にプログラミングする必要なく API テストページを作れるのは便利で、プログラミング時と同様にコメントを残したくなることもあると思います。 が、YAML でコメントを書いたことがなかったので、改めて明示的にコメントを残そうとした際の手法がわからず、調べてみました。

答えとしては「# から行末までがコメント」となるようです。つまり一行単位でコメントが生成されます。「ここからここまで」という範囲コメントは存在していないようです。
info:
  description: 普通の行
#  description: コメント行
  titie: タイトル   # ここはコメント  

なお、コメント扱いにしたくない # を含めたい場合は \# のようにバックスラッシュでエスケープすることで実現できます。




 

このページのトップヘ