この記事は東京海洋大学NePPの Advent Calendar 2024の17日目です。
はじめに
serializerとは
オブジェクトのデータをフォーマット化して外部に送信するために使われます。
特にWeb API開発では、アプリケーションの内部データをJSONやXMLなどの形式に変換する役割を担います。
serializerを使うきっかけ
問題
インターン先でAPIモードで、Railsを使用していましたが
Railsの通常モードでは、HTMLビューを通じてレスポンスをレンダリングしますが、APIモードではHTMLビューがありません。そして、コントローラーでビューに、ステータスコードとjson形式のデータを返さないといけません。
そのため、レスポンスを返す時にデータをjson形式にする必要があります。
しかし、Railsは基本的にjson形式で変数を扱っていません。
解決策
そこで、serializerを使ってみた!
serializerを導入するメリット
serializerを使うことで、そこで得られるメリットも紹介していこうと思います。
1.セキュリティの担保
モデルをそのままレスポンスに使用すると、不要なデータ(例えば、パスワードなど)がクライアントに露出するリスクがあります。
serializerを使うことで、必要なデータのみをレスポンスに含めるよう制御することができます!
例
モデルそのものが持つ属性
{ id: 1, name: "hashimoto", password_digest: "123456789" }
以下を設定することで、シリアライザーを設定
class UserSerializer < BaseSerializer
attributes :id, :name
end
serializerを使ったことによってレスポンスを以下のように制限できる。
{ "id": 1, "name": "hashimoto" }
2.コントローラーの肥大化回避
serializerを使わないと、コントローラでレスポンスデータの整形や加工を直接行う必要があり、コードが肥大化してしまいます。
しかし、serializerを導入することで、レスポンス整形のロジックをコントローラから分離できます。これにより、コントローラがシンプルになり、保守性が向上します。
例
serializerを使わない場合のコントローラーの例
def show
user = User.find(params[:id])
render json: { id: user.id, name: user.name, email: user.email }
end
serializerを使った場合のコントローラー
def show
user = User.find(params[:id])
render json: UserSerializer.new(user)
end
3.条件付きのレスポンスの柔軟性
シリアライザーの条件付き属性(attribute :name, if: :condition? など)を利用することで、動的なレスポンスを簡単に作ることができます。
または、
def include_email?
@options[:include_email]
end
などを使って、エンドポイントごとに、include_emailを使うかどうかの判断をコントローラーに任せたりすることができます。
4.再利用性
レスポンス整形ロジックがコントローラやモデルに埋め込まれていると、他のエンドポイントで再利用が難しくなると思います。
しかし、serializerを導入することで、同じモデルを扱う複数のエンドポイントで共通のロジックを再利用できます。
これは、実際に開発していてめっちゃ便利だなと思ってました。他の人が書いたserializerのコードを使いまわせるのは、コード量も減りますし、Railsの基本理念同じことを繰り返さないに少し、沿っていていいなと思いました。
5.無駄なデータの送受信
モデルそのものが持つ属性
{ id: 1, name: "hashimoto", password_digest: "123456789" ,email: "hashimoto@gamil.com"......}
以下を設定することで、シリアライザーを設定
class UserSerializer < BaseSerializer
attributes :id, :name
end
serializerを使ったことによってレスポンスを以下のように制限できる。
{ "id": 1, "name": "hashimoto" }
必要なデータのみの送受信によってパフォーマンスが上がるのかなとかってに思いましたが、これに関しては、あまり他の記事でも見かけないのでそこまで関係ないのかも。(自分の中での仮説です、、、)
おわり
セキュリティの担保やコードの可視性などを上げることができるとっても便利なserializerのメリットと自分が導入した経緯をお伝えしてきましたが、この記事が誰かの役に立てれば嬉しいです!