FORCIA CUBEフォルシアの情報を多面的に発信するブログ

npmパッケージを組み合わせてSwaggerの定義ファイルをいい感じに書く

2019.03.29

エンジニア テクノロジー 開発事例

 旅行プラットフォーム事業部の龍島です。今回は技術的な内容として、Swagger(OpenAPI)とnpmパッケージ周りのことについて書きます。
 フォルシアではAPIを作成する際、案件によってはSwaggerを利用しています。その定義ファイルをいい感じに書ける環境をnpmパッケージを組み合わせて作ったよ。というお話です。

Swaggerとは?

 SwaggerとはREST API仕様を記述するフォーマットです(公式)。


Swagger.png  このフォーマットで書くと何が嬉しいかというと、下記のようなことができます。

  • API仕様書HTMLの自動生成
  • APIサーバのスタブの自動生成
  • APIクライアントのソースコード自動生成

 Swaggerに準拠したフォーマットで記述することによって、定義ファイルを配布するだけで、利用者はスタブの作成やクライアントのラッパーを作成することができます。とても便利ですね。

課題

 利用を始めた段階では、定義ファイル(以下swagger.yml)の執筆にSwagger Editorを利用していました。自動で文法チェックを行ってくれたり、右側に表示されるプレビューが即時に変更されたりすることはかなり便利でしたが、いくつか欠点もありました。

swagger.ymlを分割できない

 Swagger Editorはswagger.ymlが一つであることが前提とされています。しかしAPI仕様が複雑、膨大になるに連れて一つのyamlファイルでなく、複数に分割して管理がしたくなってきます。

お気に入りのエディタは使えない

 Swagger Editor自体かなり書きやすくは作られていますが、やはり使い慣れたエディタには敵いません。フォルシアではいろいろなエディタ(Vim, Emacs, Sublime, VSCode, ...)のユーザがいるため、どんなエディタでも書けると嬉しいなと考えるようになりました。

解決策

swagger.ymlを分割する

 How to split a Swagger spec into smaller filesこちらの記事を参考に、ファイル分割を可能にしました。JSON ReferenceというJSONで外部ファイルを参照できるようにする(まだドラフトの)機能があり、それを用いています。記事の著者がnpmパッケージも公開しているため、それをそのまま用いました。
 内部的にはyamlファイルをパースしてjsonに変換した後に、whitlockjc/json-refsというJSON Referenceを実行するライブラリで結合しているようです。
 npmのwatchライブラリを用いて、分割したファイルのいずれかに変更があれば結合するスクリプトが走り、swagger.ymlが生成されるように設定しました。

好みのエディタで書く

 Swagger Editorを使わない場合、swagger.ymlからHTMLを作成できるツールが必要になります。標準で用意されているswagger-uibootprint-openapiなどいろいろと選択肢はありますが、今回は見た目の良さを重視してReDoc-cliを利用しました。これは好みだと思うので好みのものを選べば良いと思います。
 swagger.yml分割の際と同様に、生成されたswagger.ymlの更新をwatchし、更新されると自動的にHTMLが生成されるよう設定しました。

ブラウザのオートリロード

 swagger.ymlを分割し、swagger.ymlからHTMLを作成できるようになりましたが、Swagger Editorで実現できていたリアルタイムプレビューが実現できていません。webpackで実現されているHMRなどのように、ブラウザに手を触れること無く変更結果をみたいですよね。HTMLに更新があれば自動的にブラウザ側が更新される仕組みにできないかと考えました。
 調べているとlight-serverというパッケージが目的に一致していそうでした。説明には下記のような記述があります。

  • A simple static http server
  • Trigger browser reload if watched files change

 重厚長大な仕組みは作りたくなかったため、シンプルで欲しい機能のあるlight-serverを利用することにしました。
 package.jsonに下記のように書いておけば./build/html以下のhtmlファイルに変更があった場合にページを開いているブラウザが自動的にreloadされます。

  "watch:html": "light-server -s ./build/html -p 4000 -w \"./build/html/**/*.html # # reload\""  

 これで完全に目標は達成されました!

まとめ

 Node.jsやnpm周りを触っていると本当にエコシステムが充実していて、やりたいと思うことは大体いくつかのパッケージを組み合わせれば可能になります。利用できるものは利用し、必要なものがなければ自分で作って公開することでよりエコシステムを充実させていければいいなと考えています。

 フォルシアでは共により良いものを効率的に作っていけるエンジニアを募集しています!

 新卒の方はこちらキャリアの方はこちらからご確認ください。

この記事を書いた人

龍島広人

旅行プラットフォーム事業部 エンジニア 2016年新卒入社。
旅行会社の新規アプリ開発や社内開発インフラ業務を主に担当。
興味のある分野はDevOpsや仮想化技術。