API仕様書を分割したら不幸や悲しみから解き放たれる様です

diffeasyでエンジニアをしている新谷です。
主にBack-endを中心に、いろんな領域に強くなれる様に日々奮闘してます。
本業はアイドルのプロデュースをしています、今すぐ「アイドルマスター」で検索してください。

今回は、

- OpenAPIの管理方法を変更したら不幸や悲しみから解き放たれる…かもしれない話
- 弊社というか自分がやろうとしているAPI仕様書管理の概念的な話

を皆さんにお伝えしていきます。
今回登場するツールの使い方は、先人がドキュメントを残してくれてたりするので割愛します。

この記事の概要は、

- 1. なぜOpenAPI形式のAPI仕様書を分割するのか？
- 2. 分割したことでどうなったか
- 3. まとめ

となっております。

## 1. なぜOpenAPI形式のAPI仕様書を分割するのか？
弊社では全案件共通ではないですが、OpenAPI形式でAPI仕様書を書いています。

多くのAPI仕様書がそうである様(そうなのか？)に、API仕様書はswagger editorを用いて書いています。
API仕様書の行数が増えてくるとswagger editorを使っているとある問題に直面します。
ちなみに今、自分が携わっている案件のAPI仕様書は6,000行くらいです。
Oh...
<img width="733" alt="スクリーンショット 2019-12-21 20.59.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221827/52db9c9b-cf59-3d5e-468e-1685ac4acd23.png">

そう、API仕様書が6,000行近いとswagger editorの動作が非常に重たくなるのです。
カーソルを1文字ずらす、文字を入力する、それを変換する、文字を削除する、1つ1つの行為にラグが発生してストレスフルになっていきました。
(ここまで読むとswagger editor使わなければいいじゃないか、と思われるかもしれませんがまさにその通りなんですがその話は後ほど。)

monolithicなAPI仕様書をなんとか軽くしたいとなった時に思い付いたのが「分割」でした。

## 2. 分割したことでどうなったのか
「分割」すると「結合」が必要です。

幸いにもインターネットで「swagger 分割」等と検索すると、たくさんの先人の記事がヒットします。
私はたまたま最初に読んだ記事が「multi-file-swagger」というnpm packageを利用していたので導入してみました。
いろんな記事を読んでみると分かるのですが、大体のnpm packageはやっていることは一緒なので好きなnpm packageを導入したら良いのではないでしょうか。
分割方法も丁寧に書かれていますので参考になると思います。
結局、今は「swagger-merger」を使ってます。(なぜこちらを使う様にしたかは失念しました…)

API仕様書を分割したことにより

- 結合後のAPI仕様書に誤りがないか確認するためにlinterを導入
    - CIでvalidでないとmaster branchへのmergeをさせない
    - linterを通すからVS codeなどで雑に編集してもvalidなAPI仕様書が作れる

の副作用が得られました。

副作用で光は見えたんですが、正直なところswagger-editorを使うことによるストレスと分割にかけるコストを考えると一概にも分割すると幸せになれるかというとそうではありませんでした。
6,000行程度であればlinterを通す前提でVS Codeによる編集でもいいと思います。

### [副作用] 結合後のAPI仕様書に誤りがないか確認するためにlinterを導入 
今までswagger editorを使っていたのでAPI仕様書を常にvalidな状態に保つことが出来たのですが、使わなくなったためにvalidになっているか分かりにくくなりました。
OpenAPIのlinterとして「speccy」を導入しました。

#### [副作用の副作用1] CIでvalidでないとmaster branchへのmergeをさせない
API仕様書を管理しているrepoとCIを連携させて、git push時にspeccyによるAPI仕様書がvalidか確認する様にしました。
これによりinvalidなAPI仕様書はmasterにmergeされず、うっかり公開されるという悲しみから解放される様になりました。

とは、まだなってません。
というのもAPI仕様書をyamlからhtmlへと閲覧可能なフォーマットに変換しているのですが、今まで問題なく閲覧出来ていました。
が、speccyを入れることによりstrictなOpenAPIになる様に果てしなくinvalidな箇所を警告してくれて、いつまで経ってもmasterへのmergeが出来ず最新のAPI仕様書が公開出来なかったのでspeccyによるチェックは今のところしてません。

<img width="398" alt="スクリーンショット 2019-12-21 21.42.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221827/b6ca30b5-6930-b9ed-c1ad-5b02b13de50a.png">
こんな感じの警告が果てしなく出てinvalidとなります、悲しみ。

新規案件などで設計初期段階からsceccyを入れておかないとだいぶツラいことになります。

#### [副作用の副作用2] linterを通すからVS codeなどで雑に編集してもvalidなAPI仕様書が作れる
雑に書けば当然speccyに警告され修正箇所を教えてくれるので、OpenAPIに馴染みのないエンジニアも安心して触れるので幸せになれます。

と言っても、[副作用の副作用1]に書いてる通り今のところ幸せになれてません。

## 3. まとめ
### API仕様書の分割管理はやると不幸や悲しみから解き放たれますか？
システム規模というかAPI本数によります。
swagger-editorで編集するのが重くなってきたから分割するか！は良い選択肢ではないでしょう。
しかし、API仕様書を分割することではなく、副作用の方で不幸や悲しみからは解き放つことが出来るかもしれません。

### これがAPI仕様書の管理のベストプラクティス！？
1. 案件の初期段階でAPI仕様書を作り始める際に「speccy」を導入してvalidなOpenAPIを保つ。
    1. repoとCIとを連携してvalidでなければmasterにmergeさせない。
2. 仕様書を書く作業以外を自動化する。
    1. yamlからhtmlに変換する作業はgit pre-commitで行う。(huskyなどを使うのもヨシ)

API仕様書の「分割」はオプションとして考えておきましょう。

### 最後に
なぜ、API仕様書にここまで力を入れているかというとBack-endとFront-endでopenapi.yaml/.jsonを使って **APIのi/oを担保** しています。
そのためAPI仕様書は常に最新であるためにスピードが求められ、常にvalidであり続けるためにミスのなさを求められます。
この記事を読んで、最新でvalidなAPI仕様書が1つでも増えてくれたら嬉しいです。

API仕様書がそのシステムを使ってくれる方々を幸せにしてくれると私は疑いません。