Rails で複数の Grape API をマウントする際の問題
概要
Rails アプリにマウントしようとしている API が 2 つあります。1 つは「v1」、もう 1 つは「twilio」です。各 API は複数のファイルで構成されるため、それぞれに独自のフォルダーを作成したいと考えています。 app/api ディレクトリ内には、「v1」と「twilio」という 2 つのフォルダーと、2 つの API をマウントするために使用しようとしている「api.rb」というファイルがあります。その内容は次のとおりです。
module API
class V1 < Grape::API
prefix "api"
format :json
mount API::Root => '/v1'
end
class Twilio < Grape::API
prefix "twilio"
format :xml
mount API::Twilio_API => '/twilio'
end
end
「v1」ディレクトリには、次のように始まる「root.rb」というファイルがあります。
module API
class Root < Grape::API
version 'v1', :using => :header
...
「twilio」ディレクトリには、次のように始まる「twilio_api.rb」というファイルがあります。
module API
class Twilio_API < Grape::API
version 'v1', :using => :header
...
私のルートファイルには次のものがあります:
mount API::V1 => "/"
mount API::Twilio => "/"
Rails サーバーを起動すると、次のエラーが発生します。
`load_missing_constant': Expected [My rails app]/app/api/v1/root.rb to define Root (LoadError)
root.rb は確かに Root クラスを定義しているので、これは理解できません。助けていただければ幸いです。
解決策
Grape では、複数の API を別の API にマウントできます。つまり、API の「基本」クラスを 1 つだけ用意し、他のすべてをそこにマウントできるということです。
ファイル構造:
app/
api/
v1/
v1_api.rb
twilio/
twilio_api.rb
api.rb
アプリ/api/api.rb:
require 'v1/v1_api'
require 'twilio/twilio_api'
module API
class Base < Grape::API
mount API::V1
mount API::Twilio
end
end
アプリ/api/v1/v1_api.rb:
module API
class V1 < Grape::API
prefix "v1"
format :json
get :hello do
{ text: 'Hello from V1' }
end
end
end
アプリ/api/twilio/twilio.rb:
module API
class Twilio < Grape::API
prefix "twilio"
format :xml
get :hello do
{ text: 'Hello from Twilio' }
end
end
end
config/routes.rb:
mount API::Base => '/api'
Rails サーバーを再起動すれば準備完了です。また、app/api/twilio ディレクトリと app/api/v1 ディレクトリからファイルを簡単に自動ロードできるはずなので、それらを必須にする必要はありません。