OpenAPIのススメ

この記事は [株式会社TRAILBLAZER Advent Calendar 2024](https://qiita.com/advent-calendar/2024/trail-blazer) の10日目の記事です。

---
こんにちは、株式会社TRAILBLAZERでテックリードをしております [@joy04d](https://qiita.com/joy04d) です。

最近は、寒さと運動不足対策としてエアロバイクを漕ぎながら仕事していたり、十数年ぶりに続編がリリースされた[某ゲーム](https://www.stalker2.com/ja)を、苦境の中リリースしてくれた開発陣に感謝の正拳突きをしながらプレイしたりしております(=ω=)

## WESTERの紹介
そんな私ですが、普段のお仕事では、主にJR西日本のプロダクトである[WESTERアプリ](https://wester.jr-odekake.net/wester_app)の開発チームとして働いております。

このプロダクトについて軽く紹介させて頂くと、JR西日本グループのサービスを利用される方々の日常に寄り添うアプリとして、
- 時刻表・運行情報確認や経路検索といった移動ナビの機能を備えていたり
- JR西日本グループの提供するWESTERポイントを貯める・使うための各種機能を備えるポイントアプリとしての機能もあったり
- JR西日本グループが提供する様々なサービスへの入口としてのポータルアプリという側面もある

という複合的なプロダクトとなっています。

さて、この辺りからが本題なのですが、お察しの通りこれらの多様な機能が1システム上ですべて実装されているわけではありません。様々なシステム間をAPIで相互連携することで実現されています。

そしてAPI連携に欠かせないものといえばAPI仕様書。

このAPI仕様書を統一規格で書きたいと思ったときに出てくるのが、タイトルにもあるOpenAPIになります(=ω=)

## OpenAPIの紹介
[OpenAPI](https://github.com/OAI/OpenAPI-Specification/)とは、REST APIのインターフェイス定義の記述仕様(APIスキーマ)になります。

正式にはOpenAPI Specification(OpenAPI仕様)と呼ばれるもので、元々はSwagger Specificationという名前でしたが、Linux Foundation他名だたる企業の支援のもとに標準化されるにあたって、名称が変更になりました。

少しややこしいのですが、元になったSwagger仕様の提供元から、歴史的経緯で今もSwaggerの名前でツール群が提供されているため、OpenAPI仕様を元にした → Swaggerツール群が今もある、みたいに覚えておくと多少混乱しにくいかもしれません🤔

今のところ、REST APIの記述仕様としてはデファクトスタンダードと言って良いものになります(=ω=)

### 基本編
記法としては、YAMLかJSONを用いることができます。

YAMLでサンプルを挙げてみると
```yaml
openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9

servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing

paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML.
      responses:
        "200": # status code
          description: A JSON array of user names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
```
のような形で記載すれば、[Swagger UI](https://github.com/swagger-api/swagger-ui)を用いて

![スクリーンショット 2024-12-09 10.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301428/61497fd0-1e01-3049-cfeb-406b9e108938.png)
のような仕様書をすぐに起こすことができます。

基本構造については[こちら](https://swagger.io/docs/specification/v3_0/basic-structure/)をさらっと眺めつつ、web上で試せる[Editor](https://editor.swagger.io/)も提供されているので、軽く触って頂ければよりイメージは掴みやすいかと思います(=ω=)

### ちょっとだけ応用編
[データ型](https://swagger.io/docs/specification/v3_0/data-models/data-types/)としては、JSONSchemaを基準に、`string`,`number`,`integer`,`boolean`などの基本型に対してvalidationとして
- min - max の length指定
- ` '^\d{3}-\d{2}-\d{4}$'` のようなpattern指定
- `date`や`date-time`などのformat指定

などが可能です。

また、共通部分を[コンポーネント化](https://swagger.io/docs/specification/v3_0/components/)することが可能で、例えば
- `schemas`で`User`モデルなどを定義したり
- `responses`で共通エラーを定義したり
- `securitySchemes`で共通の[認証](https://swagger.io/docs/specification/v3_0/authentication/)を記載する

ことなどができます(=ω=)

### で、何が嬉しいの？
**構造化データである**、これに尽きると思います。
これにより
- [Swagger UI](https://github.com/swagger-api/swagger-ui)や[Redoc](https://github.com/Redocly/redoc)などを用いて、API仕様書をすぐに生成できたり
- そのAPI仕様書(というかwebページ)からテストAPIが送信できたり
- [Prism](https://github.com/stoplightio/prism)などを用いて、すぐにmockサーバーが立ち上げれたり
- [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator)などを用いて、型定義やAPI層、テストコードなどを自動生成できたり

します。
自前で活用することもできますし、他にも様々なツールが作成されたりしているので、気になる方は[公式のリスト](https://tools.openapis.org/)を覗いてみてください(=ω=)

### さらなる世界へ
さらに言うと、これらを活用すれば、先にAPIスキーマを定義して、その定義を元に各ツール群で自動化を行いながらバックエンド・フロントエンドを並行的に開発する手法を取ることができるようになります。これはスキーマ駆動開発と呼ばれていたりします。
(OpenAPI Generatorの中の人の[解説](https://speakerdeck.com/akihito_nakano/gunmaweb34)がわかりやすいので、参考まで)

部分的な活用でも十分に効果がありますが、ここまで活用できれば、より幸せな世界が待っているかもしれません(=ω=)



## 最後に
今回はOpenAPIの紹介をさせていただきました。
ご笑覧いただければ幸いです。

初期の学習コストや時々ハマリポイントがあったり、PJの途中から導入するのは中々骨だったりしますが、それらを超えれば十分なリターンが得られる技術だと思います。ぜひ検討してみてください。

また、より幸せな世界を目指して一緒に進む仲間を募集したりもしています。
最後に貼り付けておりますので、興味持っていただけた方は確認頂ければより嬉しいです。

ここまでありがとうございましたm(_ _)m

https://hrmos.co/pages/trail-blazer