こんにちは。エンジニアリング事業本部の@leafと申します。
今回はプロジェクトでOpenAPIを利用したので、作成からGitHubActionsを利用してチームに共有するまでどのように進めたかを紹介したいと思います。 まだまだ模索している部分もありますが、参考にしていただければ幸いです。
OpenAPIはREST APIのAPI定義を記述するための仕様です。 定義はYAMLまたはJSON形式で定義することができ、プロジェクトの言語に依存しないため様々な案件で利用することができます。 また、Swagger UIなどを利用することで、ドキュメントとして確認することもできます。
参考:https://swagger.io/docs/specification/about/
次はOpenAPIの定義をどのように作成していたか紹介していきます。 OpenAPIはYAMLかJSONで記述することになるので、初めの頃はVSCodeにプラグインを入れて、参考になりそうな定義を見ながら頑張って書いていました。
この時、追加していたプラグインは下記の二つです。 ・Swagger Viewer : リアルタイムに定義がどのように表示されるか確認できるやつ。 ・OpenAPI (Swagger) Editor : 左にメニューが追加されて選択した箇所にジャンプしたりできます。他にも色々してくれるっぽいです。
実際のエディターはこんな感じ。
しかし、定義方法を覚えるまでは思い通りに定義を作成するのが大変で、いい感じに解決できないかなーと探していたところ「Stoplight Studio」というツールに出会いました。 こちらのツールは、GUIで定義を作成することができるため、直感的に必要な定義を作成することができました。 また、編集方法をGUIとCodeで切り替えることもできるため、基本的にはGUIで作成し、似たような定義を量産したい場合はCodeを直接編集するみたいな使い方ができるのところがとても助かりました。
実際の画面はこんな感じ。(右上にあるFormとCodeを選択することで編集方法を変更できます。)
YAMLやJSONを書くのに疲れたという方は是非利用してみてください。
最後にチームへの共有です。 作成したOpenAPIはGitで管理を行っていたのですが、それだと更新するたび他のメンバーに最新の取り込みをお願いすることなるため不便でした。 そこで、GitHub Actionsでデプロイ時にOpenAPIの定義をHTMLファイルに変換し、それをS3で公開することで、いつでもリンクを開くだけで最新の定義を確認できる仕組みを作成したので紹介していきます。
今回はチームメンバーにのみ公開をしたかったのでIPで制限を行いました。 新しくバケットを作成し、「アクセス権限 -> バケットポリシー」に制限の定義を行います。 サンプルはこんな感じです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ConditionalReadObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::smashop-reference/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": 【ここに公開するIPを定義、配列で複数定義も可能。】
}
}
}
]
}
ここでの注意点は、Actionに「s3:GetObject」を指定するところです。 今回はGitHub Actionsを利用してデプロイを行っているため、ここで全ての操作にIP制限をかけてしまうと、デプロイ時に失敗します。
次に作成したバケットにディレクトリを作成し、公開設定を行なっておきます。
「ディレクトリ作成 -> ディレクトリを選択 -> アクションタブから公開」で公開することができます。
これでS3側の設定は完了です。
GitHub Actionsではmasterにpushが実行された際に、「ReDoc」というライブラリを利用してHTML変換、それをS3に配置するまでを行います。 HTML変換については、Swagger UIを利用する方法でもいいのですが、ReDocの方が定義とサンプルを並べて確認できるところが見やすいため、今回はこちらを採用しています。
サンプルは下記の通りです。
name: OpenAPI Build and Push HTML to S3
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node: ["12.4.0"]
steps:
- name: Checkout # 最新コードの取得
uses: actions/checkout@v2
- name: node setting # Redocでnpmを使うのでNodeの設定
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: install redoc # Redocのインストール
run: npm install -g redoc-cli
- name: build openAPI file # OpenAPIの定義をHTMLに変換
run: redoc-cli bundle ./reference/smashop.v1.yaml # プロジェクトのディレクトリに合わせて変更してください。
- name: Output file contents # 問題があった場合に確認するために中身を出力
run: cat ./redoc-static.html
- name: Configure AWS credentials # S3にファイルを配置するために権限の設定
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_DEV_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_DEV_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: S3 copy # 生成したHTMLファイルをS3に配置する
run: aws s3 cp ./redoc-static.html s3://smashop-reference/smashop/smashop_v1.html # S3のパスは先ほど作成したディレクトリに合わせて変更してください
基本的にはこんな感じの流れで成功すると思います。 ReDocの実行とS3の配置は環境に応じてパスの変更、AWSのキーも設定に合わせて変更が必要なので注意してください。
公開されているファイルを確認する時は、S3からURLを開くのが簡単です。
下記画像の用にオブジェクトを選択すると出てくるポップアップから、オブジェクトのURLというリンクを開くことで確認できます。
実際にリンクを開くとこんな感じで確認できます。
ここをブックマークしておくことで、いつでも最新の定義が確認できる感じです!
今回はOpenAPIについての紹介をさせていただきました。 ここまで整備すると、API仕様に関するコミュニケーションコストを下げることができるので、今後もうまく活用していきたいと思っています。 今後は、IP制限をもう少しいい感じにしたり、定義が増えた際にどのように管理するかなど色々な課題があるので、その辺をもう少し詰めていきたいと思います。