OpenAPI（Swagger）導入

この記事は [BitStar Advent Calendar 2023](https://qiita.com/advent-calendar/2023/bitstar) の18日目になります。

今回は昨年から開発している [BitStar Match](https://bitstar.tokyo/match/) で導入したOpenAPIについて、RailsでのAPI開発に使える便利なライブラリやツール、またそれに伴う開発手法の選定も含めて紹介していきます。

## OpenAPIとは
OpenAPIは「OpenAPI Specification」の略で、REST APIのインタフェースを定義するためのフォーマットのことです。
以前はSwagger Specificationとして知られていましたが、SwaggerがOpenAPI Initiativeへ寄贈されたことで名称がOpenAPIに変更になったようです。

## Swaggerツールセット
名称がOpenAPIに変わったことでSwaggerという言葉はもう古くなったのかというとそうではなく、現在の「Swagger」はOpenAPIでREST APIを設計する際のツールセットを指す言葉として使われています。（まあおそらくそこまで明確に区別して使ってる人はそういないんじゃないですかね）

では次にそのSwaggerツールを紹介していきます。

### [Swagger Editor](https://swagger.io/tools/swagger-editor/)
OpenAPIのスキーマを編集するためのツール。プレビュー機能がついているので手軽に確認しながら編集できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628237/ae31d132-42ea-2a62-49fa-7cc73b55cf81.png)

### [Swagger UI](https://swagger.io/tools/swagger-ui/)
OpenAPIのスキーマをブラウザ上で閲覧・操作可能な形で良い感じに生成してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628237/04c81736-04e5-8029-58eb-6f711c5fb786.png)

### [OpenAPI Generator](https://openapi-generator.tech/)
OpenAPIのスキーマを元にバックエンド/フロントエンドのソースコードを自動で生成してくれます。あらゆる言語に対応しているのが強み。
ちなみに同じような機能を持ったツールとして [Swagger Codegen](https://swagger.io/tools/swagger-codegen/) がありますが、OpenAPI GeneratorはSwagger CodegenをForkしたものであり、現在の主流はOpenAPI Generatorになっています。
（そこに至るまでには色々と変遷があったようです。詳しくは [こちら](https://speakerdeck.com/akihito_nakano/gunmaweb34) をご参照ください。）

## 開発手法の選定
ツールは他にも色々とあるのですが、ここで重要なのはどれが使いやすいかではなく、そのツール群を活かしてチームとしてどの開発手法を選択するかだと思います。
大きく分けると開発手法は以下の2種類に分かれます。

#### <INS>スキーマファースト（スキーマ駆動）開発</INS>
OpenAPIのスキーマ定義からスタートする開発手法です。
1. スキーマ定義（Swagger Editor）
2. 1で作ったスキーマを元にフロントエンド/バックエンドAPIを開発（OpenAPI Generator / Swagger Codegen）
3. テスト
4. リリース

###### メリット
- フロントエンドとバックエンドを並行して開発できる
これが何よりの強みだと思います。特に大規模開発になるほどこの開発フローは優位になりそうです。
###### デメリット
- スキーマファイルを書くための学習コストがかかる。
これについては [Stoplight Studio](https://stoplight.io/) というGUIで定義できるツールもあるので一つの選択肢になると思います。

#### <INS>コードファースト開発</INS>
一方でこちらはバックエンドの開発からスタートする開発手法です。
1. バックエンドのAPI開発
2. 1で作成したAPIのソースコードからスキーマを自動生成
3. 2のスキーマを元にフロントエンドの開発（OpenAPI Generator / Swagger Codegen）
4. テスト
5. リリース

###### メリット
- ソースコードからスキーマファイルを生成するのでOpenAPIをあまり意識せず仕様定義が可能になる
- このフローを採用するだけで仕様書と実装の乖離が発生することをほぼ完璧に防げる
###### デメリット
- API開発 → フロントエンド開発の流れが固定されてしまう
ちょっとした仕様の修正であってもフロントエンドは常にAPIの開発を待たなければいけないので、そこは開発効率の面でデメリットになり得ると思います。

## RailsでAPI開発する際の選択肢
ここまでを踏まえて、RailsでAPI開発する際に取れる選択肢を挙げていきたいと思います。

#### <INS>スキーマファースト開発の場合</INS>
スキーマ駆動開発の流れは上述した通りですが、この開発フローを取る際に一番注意するべきポイントは、実装したAPIと定義した仕様との間に乖離が発生しないようにする必要があるということです。
committee-rails というGem利用すると、それをテストでカバーすることができるようになります。

https://github.com/willnet/committee-rails

また、フロントエンドはAPIがまだ完成していない状態で実装に取り掛かることになるため、フロントエンド側でダミーデータを用意するかあるいはモックサーバーを用意する必要があります。
ここはAPIスキーマからモックサーバーを立てるツールとして Prism や msw 等があるため、そちらを利用することをお勧めします。

https://github.com/stoplightio/prism/

https://github.com/mswjs/msw

#### <INS>コードファースト開発の場合</INS>
コードファーストで開発する場合は記述したソースコードからスキーマファイルを自動生成するツールを利用する必要があります。 
Railsでは rswag というGemがあり、これはRailsのテストで定番のRSpecを拡張したライブラリで、記述されたテストコード（Request Spec）を元にAPIスキーマを生成してくれます。
APIの実装をしつつ、そのテストと仕様定義まで一貫して担保してくれるといったライブラリになるため、コードファーストの中でもさらにテストファーストでの開発をしやすくなるという特徴があると思います。

https://github.com/rswag/rswag

## まとめ
ここまで紹介してきたツール群を図にまとめるとこんな感じになります。

![openapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628237/842af3d0-5857-300c-cfbe-b5fe5e7013db.png)

特に重要なのはOpenAPIスキーマの定義をどの方向から行うかということです。
API設計者が直接編集する場合はそれはスキーマファースト開発であり、ソースコードから生成する場合はコードファースト開発であるということです。
間違ってもやってはいけないのはどちらからでも編集可能にしてしまうという状態です。必ずスキーマ定義は一方向のみから行うことが重要になります。

ちなみに弊社ではrswagを利用したコードファースト開発を採用しています。
採用時はチームの開発規模がそれほど大きくなかったというのと、フロントエンドの開発をバックエンドエンジニアも兼務するような開発体制だったため、その選択自体は悪くなかったかなと思っています。
しかし現状は少しずつ開発人員も増えてきており、また今後さらに開発規模が大きくなることも考慮すると、どこかのタイミングでスキーマ駆動開発にシフトすることも考える必要があるのかなと個人的には思っています。

これからOpenAPIを導入しようとする際に、どういった開発手法をとるかを考えるための一つの参考になれば幸いです。

BitStarではOpenAPIも利用して開発しているサービス BitStar Match の開発に携わって頂けるエンジニアを募集しております！

https://www.wantedly.com/projects/1508637

## 参考
- [OpenAPIとは｜Swaggerとの違いや役立つツールを紹介](https://www.aeyescan.jp/media/openapi)
- [OpenAPI Generatorを用いたクライアントコードの自動生成](https://heartbeats.jp/hbblog/2023/05/openapi.html)
- [平静を保ち、コードを生成せよ 〜 OpenAPI Generator誕生の背景と軌跡 〜](https://speakerdeck.com/akihito_nakano/gunmaweb34)