実務で、committeeを導入したので、その時のメモを書く。
経緯と問題点
弊社のサービスAは、モノリスなRailsのアプリケーションであるが、その他社内サービス複数からAPIサーバとして使われているが、Swaggerに関して色々問題があった。
など、新しいAPIを生やすのはいいが、それを管理できずに、APIについての確認依頼が飛んできて、Aサービスのエンジニアと別部署の人間がコミュニケーションを取らざるを得なかった。
そこで、名前だけ知っていたスキーマ駆動開発をググってみた所、committeeというgemを使うと良さそう。といった流れである。
committeeの説明
沢山記事があるので詳細は割愛するが、committeeは下記。
committeeは、実際のAPIリクエストやレスポンスがスキーマ定義にそっているかをチェックすることができるgemで、
実際のAPIリクエストやレスポンスがスキーマ定義にそっているかをチェックすることができ、Rackのミドルウェアとして動作します
公式gem を色々見るとだいたい分かる
committee Rails
ただ、committeeをRailsで使えるようにするのには、committee-railsが必要。
よく使うメソッドはこれ。一応参考まで
実際よくつかうのはこれ → assert_response_schema_confirm
使い方
|
|
をインストール。
rails_helper.rb
に、下記を追加。(pjによって Rails.root.join の後は変える必要がある)
|
|
2つのgemをいれることにより、assert_response_schema_confirm
が使えるようになる。
assert_response_schema_confirm
は、書かれたドキュメントとレスポンスが一致してるかテストしてくれる代物。後述する。
例 getするとuserのidとnameを返す
routing
|
|
controller
getしたら適当にuserのidとnameを返すようにする
|
|
Spec
|
|
assert_response_schema_confirm
が呼ばれた時に、rails_helper.rb
で設定した
schema_path: Rails.root.join("swagger", "openapi_sandbox.yaml").to_s
のファイルを読みに行く。
今回は、 openapi_sandbox.yaml
と設定した。
yaml
|
|
などと書く。イメージついただろうか。
成功
APIの返り値とyamlの期待値があっている
上記yamlの書き方で、json: { user: { id: 1, name: “busitora” } }
の期待値は、
id
とname
が必須であるという設定になる。
この段階でテストすると成功する
失敗
yamlにrequiredを追加するが返り値に追加しない
|
|
|
|
結果は下記
Committee::InvalidResponse: #/components/schemas/UserModel missing required parameters: age
「yamlにはageがrequireになってるのに、追加されてないよ」と言ってくれる。
返り値の型が違う時
|
|
integerなのにstringにした
|
|
結果は下記
Committee::InvalidResponse: #/components/schemas/UserModel/properties/age expected string, but received Integer: 27
型はintergerだけど、stringでかえってきてるやんけエラー
不要な値が入っている時(additionalProperties: false を外した時)
|
|
|
|
結果は下記
Committee::InvalidResponse:#/components/schemas/UserModel does not define properties: address
このオプションはPJであわせておかないと大変なことになる。
ポイントや注意点
ControllerSpecだと、そもそも動かなかったのでRequestSpecで書く必要がある。
弊社はContorollerSpecが多すぎて、そこを置き換えるがまず死ぬほどかかった。まだ残ってるのもある
オブジェクトでモデルを返す時は、テスト対象で必須なカラムのみrequiredにするべき → DBのnull が許容されているカラムに関して、 nullable: true を死ぬほど書くことになる。
そのフィールド、nullable にしますか、requiredにしますか
responseが 、 json: ""
だとテスト出来ないので、destory以外はしっかりレスポンスで操作した対象を返すべき
よく使う用語やオプション
・assert_response_schema_confirm
→ エンドポイントのjsonのレスポンスとschemaの整合性をチェック
・ prefix: “/api”,
→ 任意指定できる
・nullable: true
→ レスポンスにはあるが、nilのもの
導入してみて
全部は書けていないが、導入する価値はあったと思う。
今後直したいこと
jsonで返している値が、jbuilderだったり、レスポンスを200か204で返すかなど、まだルールが明確に決まっていないところがある。
ドキュメントのない、いわゆる化石コードのAPIを修正出来ずに、assert_schema_conform
の型に合わせられず修正できていない部分がある
まとめ
これからAPIを開発する時は、
- Schemaに必要な情報を網羅する
- 開発
- RequestSpec
としたい。そうすることで、ドキュメントとコードの整合性が保たれると思う.
参考
swaggerとopenapiの違い
もともと Swagger という名前だったものが、 OpenAPIと名前を変えてバージョン3.0がリリースされました。
Swaggerと聞けば馴染みのある方も多いと思います。
基本的にSwaggerとOpenAPIを読み替えても問題はないのですが、(ドメインとか残ってるし => https://swagger.io/specification/)
Swaggerは2.xまでで、OpenAPIは3.0からになるので、Swaggerのバージョン3というものは厳密には存在しません。
とのこと
資料や動画
[JA] How to use OpenAPI3 for API developer / @ota42y
Rails + RSpec + OpenAPI3 + Committeeでスキーマ駆動開発を運用するTips
一言
テスト書いてほしい。。。
GraphQLってなにそれおいしいのなので調べてみたい