やりたいこと
Single Page Applicationの開発などでバックエンドAPIサーバとしてRailsを利用する場合、やり取りされる request と response における JSON の keys を camelCase にしつつ、 Rails の内部処理では伝統的な snake_case を使いたいですよね。
しかも、一括に全てのAPIではなく、一部のAPIだけ先に少しずつcamelCase対応にしいきたい場合もあるでしょう。
RequestのkeysをcamelCaseからsnake_caseへ変換
ApplicationControllerにsnakeize_paramsメソッドを用意しておき、 サブクラスの Controllerのbefore_actionでparamsをcamelCaseからsnake_caseに変換したいactionsを指定しましょう。
ActionController::Parameters#deep_snakeize
ActionController::Parametersに新しいメソッドdeep_snakeizeを追加。このメソッドでparamsのkeysを深いところまでcamelCaseからsnake_caseに変換できます。
# File: config/initializers/params_snakeizer.rb
# Transform JSON request param keys from JSON-conventional camelCase to
# Rails-conventional snake_case
module ActionController
# Modified from action_controller/metal/strong_parameters.rb
class Parameters
def deep_snakeize!
@parameters.deep_transform_keys!(&:underscore)
self
end
end
end
ApplicationController#snakeize_params
ApplicationControllerにsnakeize_paramsメソッドを用意しておきます。
# File: app/controllers/application_controller.rb
class ApplicationController < ActionController::API
protected
# Snakeize JSON API request params
def snakeize_params
params.deep_snakeize!
end
end
一部のAPIへの適用
ApplicationControllerを継承するControllerで、before_action :snakeize_paramsを必要なアクションに対して指定することによって、そのアクションのparamsが自動的にcamelCaseからsnake_case に変換されます。
class UsersController < ApplicationController
before_action :snakeize_params, only: [:say_hello, :say_goodbye]
# .....
end
上記では、アクションsay_helloとsay_goodbyeが対象に指定されていますね。
全てのAPIへの適用
ApplicationControllerのbefore_actionに指定してしまえば、全てのアクションが適用対象になります。
# File: app/controllers/application_controller.rb
class ApplicationController < ActionController::API
before_action :snakeize_params
protected
# Snakeize JSON API request params
def snakeize_params
params.deep_snakeize!
end
end
Responseのkeysをsnake_caseからcamelCaseへ変換
Jbuilderの利用を仮定します。
一部のAPIへの適用
適用したいAPIのjbuilderファイルの先頭に次の行を記入しましょう。
json.key_format! camelize: :lower
全てのAPIへの適用
config/environment.rb次の設定を入れたら、全てのresponseのJSON keysはsnake_caseからcamelCase に変換されます。
Jbuilder.key_format camelize: :lower
サンプル
実際に動くサンプルrails-json-apiをお試しください。