Inside BuildIt

株式会社ビルディットのデザイナー・エンジニアによるブログです

OpenAPIを導入してみた話(sample project付属)

エンジニアの佐野です。

最近Laravelを利用しているプロジェクトで、API開発を行うタスクが湧きました。
API開発するにあたって、ドキュメント化する必要があったり、流行りのSchema駆動開発を取り入れたかったり……この辺りの問題を解決するべく技術選定を行いました。

まず、試したみたライブラリがこちら

github.com

コード上にコメントアノテーションでドキュメントを残していくというものです。
お手軽にできてよかったのですが、記述が冗長になりがち、mock serverを作って利用するといったことができない、と要件を満たせなかったので見送り。

ここで悩んでいたところ、弊社代表の富田から1冊の雑誌を手渡されました

WEB+DB PRESS Vol.108|技術評論社

こちらを読み込んでみて、OpenAPIもといSwaggerの存在を知り導入してみたところ良い感じに要件を満たせ、導入に至りました。
学習用途&導入しやすい用にsampleプロジェクトを作ったので紹介します!

OpenAPIとは?

OpenAPIもとい、OpenAPI Specificationは、RESTfulなAPIを記述するための仕様です。
APIのインタフェースをYAMLファイルで記述します。(JSONも書けます)

swagger.io

実際の内容はこんな感じに↓

  /pets:
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        '201':
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

仕様に則って記述することで、さまざまな恩恵が得られます。
たとえば……

  • YAMLファイルを元にドキュメントを生成
  • APIモックサーバーを生成
  • 仕様に則っていない記述になっていないか検証
  • componentに分割して記述

などなどです。
もともとはSwaggerという名称で開発されていたのですが、今ではOpenAPIという名称になっています。

ざっくりとOpenAPIの概要を説明しました。
手元でお試しできるようにサンプルプロジェクトを準備したので、その辺の話に移っていきます。

サンプルプロジェクト

github.com

Dockerでサービスを立ち上げてお試しできるようにしました。
(一応READMEの通りにコマンド実行すれば……すべての動作を確認できるはずです……)

ざっくりとした構成ですが、

  • swagger editor + swagger ui で、yamlファイルを編集&確認
  • apisprout でモックサーバーを立ち上げ
  • openapi generator でskelton codeを生成

という感じにしてあります。
swagger editor とか apisprout とか、なんやねんってなるので、その辺を補足します。

apisprout

github.com

golangで書かれたmock server立ち上げライブラリです。
OpenAPI 3の形式に則って記述していれば、記述したAPI定義の通りレスポンスを返すmock serverを立ち上げてくれます。
サンプルプロジェクトだとlocalhost:8000で待ち受けるようにしてあります。

たとえば、サンプルプロジェクトだと GET: /pets というAPIが定義してあるので、localhost:8000/petscurlとかでリクエストを投げると……

$ curl localhost:8000/pets
[
  {
    "id": 0,
    "name": "string",
    "tag": "string"
  }
]

と定義通りのレスポンスが返ってきます。

これがあると何が嬉しいかというと、APIの定義をしただけでレスポンスを利用したフロントエンド開発が進められる、ということです。

  1. APIの定義をする
  2. APIの実装をする
  3. API利用してフロントエンド実装する
  4. (APIに足りてない情報があったら1に戻る)

一般的には上記のようなフローになると思うのですが、mock serverがあることで(2)と(3)の過程を並行して進めることができます。
バックエンド、フロントエンド、お互いにAPI定義を信用して進めればいいので開発フローの改善につながります。

swagger-ui

swagger.io

localhost:8081 にアクセスすると見れるようになってます。
yamlファイルで定義した内容を閲覧しやすくしてくれます。

社内共有用にwikiツールみたいなものを準備しなくても楽々共有できるという感じ。 実際の見た目はこんな感じです↓

f:id:jalemy:20200330115624p:plain

swagger-editor

editor.swagger.io

localhost:8082 にアクセスすれば利用できます。
API定義ファイルとなるyamlファイルを編集するためのエディターです。
このエディターがものすごく便利で、API定義を記述するモチベーションが上がります。
補完機能がついていてサクサクかけるようになっていたり、画面右側にswagger uiでのプレビューを表示してくれたり。
他にも、openapiの仕様から外れた記述をしているとエラーを出力してくれたりなど高機能です。

たまに補完が効かなくなるときもありますが、だいたいReloadすれば直ります。
ちなみに見た目はこんな感じです↓

f:id:jalemy:20200330115650p:plain

Openapi generator

github.com

OpenAPI Specification の定義ファイルからさまざまな言語のコードを自動生成できます。
サンプルプロジェクトでは、 docker-compose run openapi-generator generate -i swagger/api.yaml -g {language} とコマンドを入力して利用してみてください。
たとえばRuby on Railsのコードを出力するなら、 docker-compose run openapi-generator generate -i swagger/api.yaml -g ruby-on-rails です。
実行すると、 ./api-skelton/ にRuby on Railsの自動生成コードが出力されます。

$ docker-compose run openapi-generator generate -i swagger/api.yaml -g ruby-on-rails
[main] INFO  o.o.c.ignore.CodegenIgnoreProcessor - No .openapi-generator-ignore file found.
[main] INFO  o.o.codegen.DefaultGenerator - OpenAPI Generator: ruby-on-rails (server)
~~中略~~
[main] INFO  o.o.codegen.AbstractGenerator - writing file ./.openapi-generator/VERSION

f:id:jalemy:20200330115715p:plain

あくまでエンドポイントが作られるだけで、ビジネスロジックは生成されません(当たり前といえば当たり前)
利用方法としては、自動生成されるコードを継承したクラスを作って、継承先のクラスでビジネスロジックを追加して実装する……というフローが良いかなと思います。

もともとはSwagger Codegenというプロジェクトがあったのですが、その辺りの経緯はOpenAPI generatorのコアメンバーである開発者のブログに掲載されていたので、そちらを見ていただくのが良いかと思います。

OpenAPI Generator - community drivenで成長するコードジェネレータ - 暁

実際にプロジェクトに導入してみた話

開発環境がDockerで構築されているので、ほぼほぼsampleと同様の構成で導入しました。docker-compose.ymlに追加するだけです。Docker素敵。 本当はコードの自動生成まで利用したかったのですが……すでに長期間続いているプロジェクトなこともあって自動生成を組み込む事は諦めました。
そのため、openapi generatorのみ取り除いて運用しています。API定義、mock serverの立ち上げに利用している感じですね。
とはいえ、既に運用されているプロジェクトでも後追いで導入しやすい点は良い点かなと!

導入当初は私自身がOpenAPIについて詳しくなかったため記述方法をよくわかっていませんでした……
ドキュメントとにらめっこしながら少しずつcomponent化して、なんとか利用しています。
yamlファイルが1000行を超えて大きくなってきているので、分割を考えないといけないな……→しかしapisproutが単一ファイルしか対応していない→swagger-mergerとか導入するか?🤔
と考えております。

追加で、API開発時に利用しているその他ライブラリの紹介です。

Postman

www.postman.com

API開発の強力な味方Postmanです。

  • GUI上でHeader情報や、body情報を入力できるのでわかりやすい
  • データを保存しておいて、他人にも共有できる
  • リクエストヘッダーや、ボディ、その他レスポンスも綺麗に整形して見れる
  • HTTPメソッドを選んで送信できるので、REST APIを作成するときに便利

こんな感じです。
Chrome拡張として公開されていたのですが、今後Chrome拡張版は廃止され、ネイティブアプリでの配信となるようです。
(Chrome拡張版を使っている方は早めに乗り換えましょう)

openapi-psr7-validator

github.com

phpunitでテストをする際にOpenAPIで定義した内容とレスポンスが合致しているか確認するためのvalidatorです。
OpenAPIを利用した開発時には、OpenAPIでの定義が拠り所となるので、こういったvalidatorがあると安心感が増します。

私はLaravelのプロジェクトに組み込んで利用してます。

おわりに

OpenAPIの利用方法、構成部分にフォーカスして書いてみました。
具体的な記述方法などについては、他に良質な記事がたくさんあるのでそちらにお任せします
あとは公式ドキュメントのspecification部分を参照すると良いです→ https://swagger.io/docs/specification/about/

OpenAPIで定義ができれば迷いが少なくなり、開発フローが効率化されます。とはいえ、より良いOpenAPIの利用方法があるはず……と疑問が沸いている昨今です。
ぜひ、このような開発プロセスの改善、ワークフローの効率化が好きなエンジニアの方とお仕事をできたら嬉しいです。
少しでもご興味のある方は採用ページからご連絡ください!

bldt.jp