REST API から GraphQL への移行戦略 - ルーティングの設定 ( Ruby on Rails )

Sommaire
前回の記事では、REST API から GraphQL への移行に向けた準備作業について紹介しました。
コントローラ内のアクションの可読性と堅牢性を、リファクタリングとテストカバレッジの改善によってどのように高めるかを見てきました。
ここでは、Ruby on Rails のルーターを適切に設定して API の 2 つのバージョンを同時に提供し、REST API を利用するアプリケーション向けにサービスの継続性を確保する方法を見ていきます。
前書き
この手順は必須ではなく、Ruby on Rails の routes.rb にデフォルトの GraphQL のエントリポイントである POST /graphql を追加するだけでも構いません。
しかし、私が関わったプロジェクトでは、API の 2 つのバージョンを明確に区別して示すことの方が適切に思えました。
説明
リクエストをフィルタリングしルーティングするために、いくつかの方法を使用できます。
各方法はユースケースによって有効ですが、URL によるバージョン管理の利用はあまり理想的ではありません。
確かに、それは API 呼び出しに不要な複雑さを導入します。要求されているリソースの隣に置くにはあまり関係のないパラメータを追加することになるからです。
そうは言っても、API をバージョン管理するためのさまざまな方法を紹介します:
- 例えば、URL のパスで API をバージョン管理できます
https://my-api.com/v1/articles
https://my-api.com/v2/articles
- または GET パラメータで
https://my-api.com/articles?version=1
https://my-api.com/articles?version=2
- カスタム HTTP ヘッダーで
X-API-VERSION=1
X-API-VERSION=2
- 最後に HTTP Accept ヘッダーで
以下の例およびこの記事の残りでは、最後の方法を使用するものとします。
有効であるためには、このヘッダーの値は MIME タイプの形式である必要があります。
ACCCEPT=application/vnd.le-nom-de-votre-organisation.vXXX
‘vnd' とバージョンの間には任意の名前を使用できます。
XXX を API バージョンの値に置き換えてください。
例
## api/contraints/version.rb
module API
module Constraints
class Version
attr_reader :version
attr_reader :default
def accept_header_vendor
"application/vnd.le-nom-de-votre-organisation.v#{@version}"
end
def initialize(options)
@version = options.fetch(:version)
@default = options.fetch(:default, false)
end
def matches?(request)
@default || request
.headers
.fetch(:accept, "")
.include?(accept_header_vendor)
end
end
end
end
## app/routes.rb
Rails.application.routes.draw do
scope module: :api, as: "api" do
scope module: :v1, as: "v1", constraints: API::Constraints::Version.new(version: 1, default: true) do
get "/posts", to: "posts#index"
...
end
scope module: :v2, as: "v2", constraints: API::Constraints::Version.new(version: 2) do
post "graphql", to: "graphql#execute"
end
end
end
クラス API::Constraints::Version のパラメータ default を使用すると、Accept ヘッダーが存在しない場合に API の最初のバージョンへ自動的にルーティングできます。
結論
この問題に対処するために gem を使用することも可能ですが、この記事で示した例でカバーされるユースケースに対しては追加の依存関係を導入する必要はないと考えます。
最後に、前述のように、REST から GraphQL への移行の文脈では、この手順は任意ですが、API の進化を明確に区別するのに役立ちます。
コメント
読み込み中...