下記のようなURL
- get
hostname.com/api/v1/customers.json
- get
hostname.com/api/v1/customer.json?hoge=...
- post
hostname.com/api/v1/customers.json
- patch
hostname.com/api/v1/customer.json
- こういうのが、なんパターンも存在する。
- ex. モデル毎に上記のようなエンドポイントが存在する
routes.rb
...
namespace :api, format: 'json' do
namespace :v1 do
get ':type' => 'base#routing'
post ':type' => 'base#bulk_create'
patch ':type' => 'base#update'
delete ':type' => 'base#destroy'
end
end
...
base_controller.rb
...
def routing
if params[:type].singularize == params[:type]
find
else
index
end
end
def index
render json: success(results: model.all)
end
def find
render json: success(results: model.find(uri_param))
end
def bulk_create
if model.bulk_create(body_params)
render json: success(message: 'bulk_create quing')
else
render json: fatal_error(message: 'bulk_create is error')
end
end
private
def model
@model ||= model_name.constantize
fail 'Not found model' unless @model.include(HogeModel)
@model
end
def model_name
@model_name = params.require(:type).singularize.classify
@model_name
end
...
やってること
-
api/v1/
以下に付随するディレクトリをパラメータとして認識 - getリクエストは複数あるため、base_controllerで上記パラメータが複数形/単数形を判断し、適切なメソッドに処理を流している
- typeを受け取り、モデル名と、該当モデルクラスを取得。
- 各メソッドでは、該当モデルクラスを呼び出し処理を実施
なにがいい?
- routes.rbに無用に同じような記述をしなくていい
- controller.rbが減る
- よって、必要なテストは減りカバレッジも上がる
問題点
- RSpecのテストの書き方がちょっとトリッキー。
- 機会があればまた紹介します。