openapi / swaggerのすすめ

本記事は[CA21 Advent Calendar 2020](https://adventar.org/calendars/5308) 23日目の記事です。

今年は長期のハッカソンに3回出場しました。

1. 6月くらい、1週間、CA21卒内定者でのハッカソン
1. 10月くらい、約1週間、[SOCIAL CREATORS](https://prtimes.jp/main/html/rd/p/000000006.000060630.html)という運営兼参加者で出たハッカソン
1. 10月末~11月、1週間＋2週間、[JPHACKS](https://jphacks.com/information/result-report2020/)でチーム"蒟蒻畑"で"おしゃべじたぶる"というアプリを開発。決勝にも出場し、いろいろ賞をもらった。リーダーが[まとめた記事](https://blog.konnyaku256.dev/posts/what-we-did-and-learned-at-jphacks2020/)を書いてくれてるのでご参考に！

3回ともサーバーサイドを担当し、openapiを使いまくってRESTful APIの作成を行いました。
そのときに得た知見について、特にGUI化、モックサーバーについてをまとめます！
（ここではopenapiの使い方そのものについては説明しません）

## [openapi / swagger](https://swagger.io/)とは
RESTful APIの仕様をjsonまたはyaml形式でドキュメント化できるものです。

```yaml:post_user.yaml
/user:
  post:
    tags:
    - "user"
    summary: "Create user"
    description: "This can only be done by the logged in user."
    operationId: "createUser"
    produces:
    - "application/xml"
    - "application/json"
    parameters:
    - in: "body"
      name: "body"
      description: "Created user object"
      required: true
      schema:
        $ref: "#/definitions/User"
    responses:
      default:
        description: "successful operation"
```
特定のツールを使うとドキュメントをGUI化できたり、apiのテストを行ったり、apiのモックサーバーを簡単に立てたりできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366447/d12a9e1c-d798-2fe6-9562-444d4fb4cd65.png)

特にハッカソンではクライアントとのドキュメントの共有やモックサーバーを立てるのに重宝しています。
ちなみにopenapiとswaggerの違いは[公式サイト](https://swagger.io/blog/api-strategy/difference-between-swagger-and-openapi/)によると以下の通りだそうです。

- openapi：記述の仕様
- swagger：openapiを実装するためのツール

## GUI化
### [Swagger Editor](https://editor.swagger.io/)
公式が提供しているエディターです。
画面左がエディターとなっており、画面右にGUIがリアルタイムで反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366447/141ed0de-ee2b-b873-aeb8-05947a40d026.png)
ログイン機能はなく、エディター部分はgit等のソースコード管理ツールとの連携はないので、外部からコピーしてきたコードをさくっとGUIでみたいときに使うのが良いと思います。

### [Swagger Viewer](https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer)（VSCodeの拡張機能）
`Preview Swagger`というコマンドが追加され、実行するとVSCodeの画面から直接Swagger Editorと同様のGUIを閲覧できます。
デフォルトの設定ではVSCode内で新たなタブを生成されますが、`Swagger Viewer: Preview In Browser`という設定項目にチェックを付けブラウザが開かれるようにすることをお勧めします。
自分の環境だとVSCode内のGUIではコピペができなかったっためです。あと重い。
以下の動画は[公式](https://github.com/arjun-g/vs-swagger-viewer)から引用
![image.gif](https://camo.githubusercontent.com/8810d409d607972bc7bfa0529e6e2fe3cbc8db2edab13595ed2a4f78bcc529fd/68747470733a2f2f63646e2e7261776769742e636f6d2f61726a756e2d672f76732d737761676765722d7669657765722f6d61737465722f646f63732f737761676765722d707265766965772e676966)

内部的にはGUI用のサーバーを立てているようです（デフォルトの設定では`localhost:18512`）。
ローカルで動くので個人で開発する際には使い勝手はとてもいいです！

### 自作
ハッカソン中での使い方として、クライアントにドキュメントを共有したいということがあります。
Swagger Editorはクライアント側でコピペの手間がいるし、Swagger Viewerはローカルで動くものなのでそもそも共有に向いていません。
できないのならば作ればいいじゃないかということで、自分で作りました。
と言ってもそんな大層なことはしてません。
実はSwagger EditorやSwagger Viewerで使われているGUIは`swagger-ui`という名前でオープンソースとなってます（[github](https://github.com/swagger-api/swagger-ui)）。
[/dist以下](https://github.com/swagger-api/swagger-ui/tree/master/dist)をコピーしてきて`index.html`の`SwaggerUIBundle`の`url`にopenapi形式のドキュメントのurlを設定するだけです。

```javascript:index.html
const ui = SwaggerUIBundle({
    url: 'https://petstore.swagger.io/v2/swagger.jsonl',  // ここを変更
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
    plugins: [SwaggerUIBundle.plugins.DownloadUrl],
    layout: 'StandaloneLayout',
});
```

githubでは`index.html`をGitHub Pagesに設定し、urlにはmainブランチのopenapiのrawファイル（Rawを押すと遷移する`https://raw.githubusercontent.com`から始まるやつ）を設定することで、常にmainブランチの最新の内容をGitHub Pages上で見ることができます。

注：urlにはhttp/httpsから始まるものしか設定できません。別の方法で相対パスによる設定ができますが、ローカルでは動くもののgithub上で動かなかったので、rawファイルのurlを設定するようにしています。

## モックサーバー
### [SwaggerHub](https://app.swaggerhub.com/)
公式が提供しているサービスです。
以下の画像は[公式](https://swagger.io/tools/swaggerhub/)から引用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366447/8a129a29-67c6-d284-f8fd-ad9cf51b6932.png)


githubと連携できたりモックサーバーを立てたりでき、Swagger Editorの上位互換的なものです。
無料プランではgithubとの連携がgithub -> SwaggerHubの片方向となっており、少し使い勝手が悪いです。
モックサーバーはドキュメントに記載されているレスポンスがそのまま返ります。

### [Postman](https://www.postman.com/)
Postmanはできることが多いので公式の説明をそのまま貼ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366447/4a9185dc-9b64-e5cc-1d73-27905d5790ef.png)
openapiをドキュメントとしてインポートさせることで、APIクライアントやモックサーバーを一瞬で立てることができます。
特にSwaggerHubとの違いとして

- インポートするopenapiはgithubと"双方向"に連携させることができる
- モックサーバーのレスポンスを自動で拡張してくれる（配列形式のレスポンスがドキュメントには1個しか書かれていなくても複数個返してくれる等）

があります。
また、Postmanがもともと持っている機能であるAPIのテストが簡単に行えるのも魅力です。
そんなこんなで最近はPostmanを愛用しています。

## まとめ
openapiの仕様を覚えるのは結構な学習コストがいりますが、一度覚えてしまえば色んなことが簡単にできるようになります！（今回は特に触れていないですが、AWSのAPI Gatewayもopenapiに対応していたりします）
単純なドキュメントとしてもかなり使い勝手のいいものなので、みなさん是非使ってみてください！

## PR
CyberAgentでは22卒エンジニアの採用を行っています！
https://www.cyberagent.co.jp/careers/news/detail/id=25511