1
0

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のserializerを導入した経緯

Last updated at Posted at 2024-12-31

この記事は東京海洋大学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のメリットと自分が導入した経緯をお伝えしてきましたが、この記事が誰かの役に立てれば嬉しいです!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?