13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails APIのレスポンスをキャメルケースに変換するテクニック

Posted at

Railsは通常スネークケースを用いてコードを書きますが、JavaScriptなどのフロントエンドではキャメルケースを好む場合が多いです。
そのため、要件によっては、RailsでAPIを構築する際にスネークケースからキャメルケースへの変換が必要になる場合があります。
ここではそんな時の変換テクニックをいくつか紹介します。

1. ActiveModelSerializersの使用

active_model_serializersというGemを使用します。

設定

initializerに以下の設定を追加し、全体でキーをキャメルケースに変換するようにします。

config/initializers/active_model_serializers.rb
ActiveModel::Serializer.config.key_transform = :camel_lower

個別のレスポンスで異なる変換を行いたい場合は、render時に指定することも可能です。

モデルのSerializer作成

それぞれのモデルに対してSerializerを作成します。
以下の例では、UserSerializerを定義し、user_idのキーを個別に指定しています。

class UserSerializer < ActiveModel::Serializer
  attribute :id, key: :user_id
  attribute :first_name
  attribute :last_name
end

このSerializerを使用してデータを返却する場合、以下のようにrenderメソッドで指定します。

 render json: user, serializer: UserSerializer
# 以下のような形式のJSONが返却されます
# {
#    userId: 1,
#    firstName: 'テスト',
#    lastName: '太郎'
# }

この方法は、複数のデータベースや親子関係にあるモデルにも適用できるため、柔軟に対応できます。
詳細な使い方については、GitHubのドキュメントを参照してください。

2. deep_transform_keysメソッドを利用してハッシュキーを変換する

ActiveSupport::Inflectorモジュールのdeep_transform_keysメソッドを利用して、ハッシュのキーをキャメルケースに変換できます。

hash = {
  user_id: 1,
  user_name: 'テスト太郎',
  details: {
    last_login: '2024-06-30'
  }
}

camelized_hash = hash.deep_transform_keys { |key| key.to_s.camelize(:lower) }
# 以下のような形式のデータが得られます
# {
#   userId: 1,
#   userName: 'テスト太郎',
#   details: {
#     lastLogin: '2024-06-30'
#   }
# }

deep_transform_keysを使うことで、ネストされたハッシュも簡単にキャメルケースに変換できます。

3. Jbuilderを使用

Jbuilderを使うと、JSONレスポンスのキーをキャメルケースに変換することが簡単にできます。

個別に設定

適用したいjbuilderファイルの中に次の内容を追加してください。

xxx.json.jbuilder
json.key_format! camelize: :lower

一括で設定

config/environment.rbに以下の設定を入れると、全てのresponseのJSON keyがキャメルケースに変換されます。

config/environment.rb
Jbuilder.key_format camelize: :lower

4. ミドルウェアを作る

ミドルウェアを作成して、Railsアプリケーションのレスポンスをキャメルケースに変換することができます。

ミドルウェアの実装

以下はキャメルケースに変換するミドルウェアの例です。

lib/middleware/camel_case_middleware.rb
module Middleware
  class CamelCaseMiddleware
    def initialize(app)
      @app = app
    end

    def call(env)
      status, headers, response = @app.call(env)

      if json_response?(headers)
        response_body = extract_body(response)
        new_body = convert_keys_to_camel_case(JSON.parse(response_body))
        response = [new_body.to_json]
        headers['Content-Length'] = response.first.bytesize.to_s
      end

      [status, headers, response]
    end

    private

    def json_response?(headers)
      headers['Content-Type']&.include?('application/json')
    end

    def extract_body(response)
      response_body = ''
      response.each { |part| response_body += part }
      response_body
    end
    
    def convert_keys_to_camel_case(value)
      case value
      when Array
        value.map { |v| convert_keys_to_camel_case(v) }
      when Hash
        value.each_with_object({}) do |(k, v), acc|
          acc[k.to_s.camelize(:lower)] = convert_keys_to_camel_case(v)
        end
      else
        value
      end
    end
  end
end

ミドルウェアの設定

config/application.rbに以下のコードを追加します。

config/application.rb
require_relative '../lib/middleware/camel_case_middleware'
config.middleware.use Middleware::CamelCaseMiddleware

使用例

body = {
  user_id: 1,
  first_name: 'テスト',
  last_name: '太郎'
}
render json: body, status: :ok: 
# 以下のような形式のJSONが返却されます
# {
#    userId: 1,
#    firstName: 'テスト',
#    lastName: '太郎'
# }

おわりに

これらの方法を活用することで、Railsアプリケーションでスネークケースからキャメルケースへの変換を効率的に行うことができます。
個人的には、active_model_serializersを使った方法か、deep_transform_keysを使った方法が好みです。プロジェクトの要件に応じて、適切な方法を選択してください!

参考

13
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?