明けましておめでとうございます。masm11 です。今年もよろしくお願いします!
grape をご存知でしょうか? Rails で API を作る時に便利ですね。
今回は、grape を使った API で URI パラメータとしてメールアドレスを受け取ろうと してハマったので、ご紹介します。
環境を用意する
まず Rails 環境を用意します。
gem install rails mkdir t2 cd t2 rails new . echo "gem 'grape'" >> Gemfile bundle install --path=vendor/bundle bundle exec rails webpacker:install
grape を組み込んでいきます。
まずはルーティングから。
vi config/routes.rb
Rails.application.routes.draw do mount Test::API => '/' end
API の実装を作成します。
vi app/api/test/api.rb
class Test::API < Grape::API version 'v1', using: :path format :json content_type :json, 'application/json' prefix :api resource '/test' do get '/:id' do { value: params[:id] } end end end
ここではとりあえず URI パラメータとして :id
を受け取るようにしてあります。
api
の大文字が Api
でなく API
になるように設定します。
vi config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'API' end
では起動してみます。
bundle exec rails s
API のエンドポイントは http://localhost:3000/api/v1/test/:id
です。
ここにアクセスしてみます。
luna:~ % curl http://localhost:3000/api/v1/test/123 {"value":"123"} luna:~ %
:id
が受け取れていますね。
メールアドレスを受け取る
ではメールアドレスを受け取るように改造します。
vi app/api/test/api.rb
class Test::API < Grape::API version 'v1', using: :path format :json content_type :json, 'application/json' prefix :api resource '/test' do get '/:email' do { value: params[:email] } end end end
params
のキーが変わっただけですね。
先ほどと同様に curl でアクセスしてみます。
luna:~ % curl http://localhost:3000/api/v1/test/foo@example.jp {"value":"foo@example"} luna:~ %
なんと .jp
が消えています。
他のメールアドレスでも試してみます。
luna:~ % curl http://localhost:3000/api/v1/test/foo@example.co.jp
この場合は RoutingError になりました。
解決策
いろいろなメールアドレスで試してみたところ、拡張子として認識されている
のでは、と思い至りました。
Rails は URL の末尾に .html
とか .json
とかを付けて、希望する
レスポンス形式を指定する機能がありますよね。
あれが効いているのでは、ということです。
api.rb の get の行を以下のように変更します。
get '/:email', requirements: { email: /.*/ } do
このように変更したところ、正しく受け取ることができました!
luna:~ % curl http://localhost:3000/api/v1/test/foo@example.co.jp {"value":"foo@example.co.jp"} luna:~ %