猫でもわかるWebプログラミング

試行錯誤しながらエンジニア(プログラマー)として働く猫のブログ。技術的な話や、働き方の話、読書録とか、試行錯誤している日常の話。

OpenAPI の運用方法についてと、OpenAPIのメリット・デメリット

f:id:yoshiki_utakata:20190411155855p:plain

はじめに

この記事はドワンゴ Advent Calendar 2019の8日目の記事です。

qiita.com

自己紹介

ニコニコ動画とNicoBoxのサーバーサイドの開発をしています。最近はAPIサーバーを新しく作ったり、保守したりしています。

NicoBoxは、ニコニコ動画にアップロードされた動画のうち、ボカロや歌ってみたなどの音楽を聴くのに特化したアプリです。ボカロや歌ってみたを聴くのであれば非常に良いアプリなので、知らなかった人は使ってみてください。

site.nicovideo.jp

(ゆるふわ)RESTの採用理由

GraphQLを採用したいけど大変そうだからRESTにしとくか 、と判断しました。

近年GraphQLが非常に流行っています。確かにGraphQLは我々にとっても非常に魅力的なものでしたが、導入するにはコストが高いと感じました。

RESTであれば、既存のコードが使えることが想像できますし、APIを利用するクライアントも使い慣れています。

便利な新しい技術の採用も重要ですが、今回はとにかく 低コスト早く リリースしたかったのです。

実際には厳密なRESTではなく、 RESTっぽい何か です。完全にリソース指向ではなく、search , recommend のような、リソースではないPathも存在しているゆるふわなRESTです。

OpenAPIを採用した理由

Confluence を使っていた

これまではAPIのドキュメント管理に、Confluence *1 を使っていました。

しかし、ConfluenceでAPIドキュメントを書くのは苦痛でした。表を作って、リクエストパラメータ書く程度であれば良いのですが、レスポンスを書くのが特に辛いです。階層構造があるので表では表現しづらいですし、サンプルレスポンスのJSONを手で書くしか無いので辛すぎました。

OpenAPIを使おう

OpenAPI は YAML 形式でAPIの定義を書くと、自動でドキュメントを生成してくれます。このドキュメントが非常に見やすいです。サンプルレスポンスも簡単にかけます。

OpenAPIとは

OpenAPI について詳しくは説明しません。OpenAPIについて知りたい人は、この記事を読むとイメージが湧くと思います。

www.kabuku.co.jp

とにかく、APIドキュメントが書くのが大変だったので、OpenAPIを採用した、というのが最初でした。

OpenAPI の運用方法

リポジトリ

OpenAPI の yaml ファイルと、 ソースコード を同じリポジトリで管理するようにしています。リポジトリが別れていると

  • あっち行ってコミット、こっち行ってプルリクマージ、 行ったり来たりがだるい *2
  • コード変更したけどドキュメントだけ忘れてる 、みたいなことに気づきづらい

ためです。

ディレクトリ構造

ドキュメントはGitHub Pagesを使って公開します。GitHub Pagesは、masterの docs ディレクトリ以下を GitHub Pages として公開する設定があるので、これを活用します。

f:id:yoshiki_utakata:20191204204318p:plain

リポジトリのルートには、docs ディレクトリがあり、ソースコード用のディレクトリがあったりします。docsディレクトリ以下はこのようになっています。

f:id:yoshiki_utakata:20191204204513p:plain

  • specs ディレクトリ以下に OpenAPI の YAML が入っています。specs以下にはindex.ymlが入っていて、これが OpenAPI の YAML です。
  • index.html は、ReDoc という、OpenAPI の YAML を元にAPIドキュメントを生成してくれるやつです。GitHub Pagesでこのindex.htmlにアクセスすると、specディレクトリ以下にあるYAMLを読み込んで、APIドキュメントを表示してくれます。

コントリビュートとCI

package.json は以下のようになっています。

{
  "scripts": {
    "watch": "http-server --cors -c-1",
    "validate": "swagger-cli validate ./specs/index.yml"
  },
  "dependencies": {
    "swagger-cli": "^2.3.0"
  },
  "devDependencies": {
    "http-server": "^0.11.1"
  }
}
  • npm run watch を実行するとHTTPサーバーが立ち上がります。手元のPCでYAMLをいじる時に、index.htmlでAPIドキュメントの生成結果を確認しながら編集できます。
  • npm validate は YAML ファイルが正しく書かれているかをチェックするコマンドです。ブランチをpushするとCIでこのコマンドが実行され、書き方が間違っている時はCIが落ちます。

OpenAPI を採用してよかった点

慣れればすごく良い

慣れればすぐ書けるようになります。修正も簡単です。表を頑張って組み直したり、サンプルレスポンスを頑張って書き直したりする必要はありません。

Code Generator が使える

OpenAPI には Code Generator というものがあり、YAMLからAPIクライアントのコードを自動生成できます。

はじめは Code Generator を利用する予定はなかったのですが、今ではガッツリCode Generatorを使っています。

OpenAPI の辛い点

正確に書こうとするとかなり大変

APIドキュメントの生成程度であれば、多少適当に書いてても動きます。

しかし、Code Generator やその他の周辺ツールを活かそうとすると、かなり厳密に書く必要があります。厳密に書けるようになるまではそこそこ学習コストがかかります。

ツールの質が微妙な時がある

我々は openapi-generator という Code Generator を使っているのですが、生成されるコードの質が微妙なことがあります。

何回か openapi-generator にプルリクを送ることになりました。

dreddというツールも使いたいのですが、OpenAPI Version 3 には完全対応していません。*3 dreddはYAMLを読み込み、APIを叩いてテストしてくれるツールです。

YAMLが巨大になると辛い

APIの数が増えてくるとYAMLファイルが巨大になります。しかし、これを分割するGoodな方法がありません。仕方ないので自分たちでなにかツールを作る予定です。

本当の意味でRESTになっていないと辛い

例えば、/recommend/video-and-playlist を叩くと「動画」と「プレイリスト」が混ざって返ってくるAPIがあるかもしれません。*4 このような真のRESTでないAPIを書こうとすると非常に辛いです。

なんとかドキュメントまでは生成できるのですが、Code Generator が対応していません。

OpenAPIに頼らないか、APIを真のリソース指向にする必要がありそうです。

ネットに知見があまり無い(気がする)

僕が日本で一番本気でOpenAPIの運用について考えている、、、かどうかはわかりませんが、我々の規模でOpenAPIを運用しているところはあまり無い気がしています。

少なくとも、僕が導入した2017年頃、ググっても何も知見が出てきませんでした。今調べたら結構出てきますね。2019年の記事が多そうです。

ちなみに、2017年の導入当時にはこの記事を参考にしました。

tech.recruit-mp.co.jp

まとめ

  • RESTを採用するのがコストが低いのでRESTを採用した
  • APIドキュメントを書くのが辛いのでOpenAPIを導入した
  • APIドキュメントを書くだけならそんなに難しくないし便利
  • Code Generator などの周辺ツール使おうとすると結構学習コストがかかるし、たまに微妙なツールもある

総合的には導入してよかったです。導入しないメリットはほぼ無いかと思います。

*1:わからない人向けに簡単に説明すると、Wiki みたいなものです。

*2:個人の感想です

*3:OpenAPI には Version 2 と Version 3 があり、Version 3 の方が表現力が上がっているのですが(Cookieについて書けるなど)、dredd は Version 2 までしか対応していません。

*4:YouTubeのおすすめって動画とプレイリストが混ざって表示されていますよね。