OpenAPI(Swagger)がYAMLを書かなくてよくなっていたのでSTORES.jpでも導入しました

この記事は STORES.jp Advent Calendar 2019 の2日目です。

私が勤めているストアーズ・ドット・ジェーピー株式会社(以下STORES.jp)はheyグループとなり急拡大している真っ最中で、それはエンジニアチームも例外ではありません。
2018年ごろまでは10人に満たないエンジニアチームで開発を行なっていたSTORES.jpでしたがここ1年くらいで30人以上のエンジニアが関わるようになりました。
まだまだやりたいことはたくさんあるので、これからもっとエンジニアチームを拡大していくことを計画しています。

そして、急拡大する中で今まで感じなかった課題が多数発生するようになりました。
その中のひとつが「APIを介したフロントエンドとバックエンドの協働が難しい」というものです。

STORES.jp開発チームで起きていた課題

STORES.jpは2018年ごろまでは少数精鋭のエンジニアチームがフロントエンドもバックエンドも両方書いて機能を実装する、という体制でした。
組織に合わせてシステム構成もRuby on Rails + (Railsに密結合している)AngularJS というものでした。

それが今ではフロントエンド専属チームが結成され、フロントエンドチームだけで9名の組織になっています。
Railsに密結合していたAngularJSは絶賛Nuxt.jsに移行中で、Ruby on Railsで実装されたAPIをNuxt.js側から叩くという構成を目指して開発を進めています。
そのあたりの様子はフロントエンドチームの @daitasu の資料をみていただければわかりやすいかと思います。

バックエンドチームも順調に拡大しており、おかげでいろんなことがスムーズに進むようになったのですが、一方で1年前まではフロントエンドもバックエンドも区別なく実装していた組織ですので、API定義がドキュメントとして残っていません。「APIを叩いて返ってきた値が定義だ」みたいなワイルドな世界観です。
そして仕方なくフリーテキストでやりとりされるAPIのドキュメントたち。書きづらそう、読みづらそう、という感情で胸が締め付けられるようです。

また、バックエンドのAPI実装よりもフロントエンドの方が先に実装が進んでしまい、バックエンド待ちでフロントエンドチームのリソースが宙に浮くといった状況も観測されるようになってきました。
開発用のモックサーバだけでも先に提供することができればこんなことには、という感情で(以下略)。

こういった状況下で真っ先に思い浮かぶのはOpenAPI(Swagger)だと思います。確かにSwaggerを導入すればAPI定義のドキュメントが用意され、それがモックサーバになるので、この状況を改善できそうです。
ただ、私が過去Swaggerが導入されているプロジェクトに参加したとき、意外とOpenAPIの学習コストが高く「また今日もYAMLしか書かなかったな...」という気持ちになったことがあったので、有効な手段とわかりつつも導入には抵抗感がありました。

Stoplight Studioとの出会い

といった中で色々調べていくと、なんと最近はYAMLを書かなくてもStoplight StudioというOSSのツールを使えばGUI上でAPI仕様が書けるようになっていました。

少し使ってみたところかなり直感的に操作できるUIで、OpenAPI仕様書とにらめっこしなくてもAPI定義を行うことができ、過去の辛い思い出がしっかり払拭されました。
さらにモックサーバもビルトインされており、起動中にAPI定義を行いながらリアルタイムにモックサーバから返されるレスポンスを確認できるので、フロントエンドの開発にもかなり役にたちそうです。

という解説と、最近開発しているAPIに対応しているYAMLファイルを添えたPull Requestをあげてみたところ

スクリーンショット 2019-11-28 14.32.33

スクリーンショット 2019-11-28 14.34.15

ということでSTORES.jpでもOpenAPI(Swagger)を導入してみることにしました。

導入に際してやったこと

Swagger導入にあたって一番の懸念点は「こういうドキュメントってメンテされにくいよね」ということでした。
今後も多数の機能拡張を行なっていく予定なので、すでにあるAPI定義と実際の実装が離れていくことは容易に想像できます。

そこで、API定義と実際の実装を自動でテストする仕組みが必要だと考えました。前述の通りSTORES.jpのバックエンドはRuby on Railsで作られているので、committee を導入することでAPI定義と実装が違ってしまった場合にテストが落ち、CIで検知できるようにしました。

committee-rails と合わせて導入することで、以下のようRSpecでAPI実装がAPI定義とマッチしているか確認することができます。

describe 'request spec', :type => :request do
  include Committee::Rails::Test::Methods

  def committee_options
    @committee_options ||= {
      schema_path: Rails.root.join('swagger/openapi.yaml'),
      old_assert_behavior: false
    }
  end

  it 'conforms to request schema' do
    get '/'
    assert_response_schema_confirm
  end

  it 'conforms to response schema' do
    post '/'
    assert_request_schema_confirm
  end

  it "conforms to response and request schema" do
    post '/'
    assert_schema_conform
  end
end

これによってCIでAPI定義と実際の実装が違ってしまったことを検知できるようになります。
またそれだけでなく、API定義を書きながらテストが行えるのでより安心感を持ってAPI定義を行うことができるようになりました。

※なお、 assert_schema_conform メソッドはデフォルトではレスポンスのスキーマのみチェックする動作になっていますが、将来的にリクエスト・レスポンス共にチェックするメソッドに変更される予定で、committee_options の old_assert_behavior を false に設定すれば現時点でもリクエスト・レスポンス共にチェックする動作になるので、今から導入する場合は前述の設定をするか、assert_response_schema_confirm のように明示的にチェックする箇所を指定するメソッドを使用すると将来的に互換性があるテストになります。参考:https://github.com/interagent/committee/blob/4d077e1277b1283ddc854578165fdb37a9cf90c7/lib/committee/test/methods.rb#L62

OpenAPIと committee については今年のRubyKaigiでも話されていたテーマなので要チェックです。

将来的にはOpenAPI定義を静的ファイルとしてとしてどこかにホスティングして、社内からならどこからでも参照できるという状態にしたいなと思っているのですが、この Chrome Extension を利用すればGitHub上でもOpenAPI定義をSwagger-UIとして見れそうだったので、今回はAPI定義のホスティングまではやりませんでした。

まだOpenAPI(Swagger)を使った開発・ドキュメンテーションができるようになったばかりなので、実際にどうワークしていくかはこれから試してみて、トライアンドエラーのループを回して初めてわかることだと思っています。

実際にどうだったかは、また将来どこかでお話できればなと思っています。

宣伝

STORES.jpをもっと良いプロダクトにしたいし、もっと楽しいエンジニアチームにできたらいいなと思っているので、興味がある方はオープンオフィスもカジュアル面談も体験入社もなんでもやっているので連絡をお待ちしております!

(STORES.jpはheyグループなので、heyグループ全体の採用・イベントページを以下に貼っておきますね)


この記事が気に入ったらサポートをしてみませんか?