素朴な疑問
筆者が新人教育する中で、プログラミング実務未経験者がよくされる質問を紹介します。
未経験者に限らず、「そういえば何のために使っている技術(ツール)なんだっけ?」とよく理解していないまま利用しているケースも少なくありません。
この記事で、その純粋で素朴な疑問を改めて明確にして理解を深めていきましょう!
今回の疑問
今回の疑問は表題通り、
「シリアライザー って何?」 です!
実務未経験者のポートフォリオレベルでは、シリアライザーを ActiveModelSerializers などのライブラリを使って導入されておらず、実務で初めてシリアライザーの存在を認識するケースが多いようです。
そこで、本記事で取り上げたいと思います!
シリアライザーって何?
Railsのシリアライザーは、データをJSON形式に変換するためのツールです。
簡単に言うと、データベースから取り出した情報をWebアプリケーションで使いやすい形に変換する 役割を果たします。
しかし、、、
「使いやすい形」とは何なんでしょうか?
そもそもなぜライブラリを使って変換しなればならないのでしょうか?
rails g scaffold
で作成されるcontrollerには下記のように記載されており、これでも問題なくjson形式に変換してレスポンスを返せます。
# GET /users/1
def show
render json: @user
end
上記が初心者の困惑するポイントだと思います。
このポイントが理解できるように次のセクションで説明致します。
シリアライザーの基本的な役割
シリアライザーの基本的な役割を下記3つにまとめました。
- データの変換
- リレーションデータの取得
- データの整形
ActiveModelSerializers
を使って変換する場合と、json: @model
を使って変換する場合との違いは下記のようになります。
ActiveModelSerializers | json: @model | |
---|---|---|
データの変換 | ○ | ○ |
リレーションデータの取得 | ○ | × |
データの整形 | ○ | × |
データの変換
データベースの情報は通常、Rubyのオブジェクトとして格納されていますが、API経由で提供する場合はJSON形式に変換する必要があります。シリアライザーはこの変換作業を行います。
リレーションデータの取得
json: @model
では、基本的にはモデルの直接の関連のみを含めることができます。
/*
json: @userの場合
- Userモデルの属性のみを返す
*/
{
"id": 1,
"name": "John Doe",
"created_at": "2023-08-07T12:00:00Z",
"updated_at": "2023-08-07T12:00:00Z"
}
一方で ActiveModelSerializers
を使うと、親モデルとそれに関連する子モデルのデータなどネストしたリレーションモデルも含めることができます。
/*
ActiveModelSerializersの場合
- Userモデルとリレーションを持つPostモデルの属性を返すことができる
*/
{
"id": 1,
"name": "John Doe",
"created_at": "2023-08-07T12:00:00Z",
"updated_at": "2023-08-07T12:00:00Z",
"posts": [
{
"id": 1,
"title": "First Post",
"content": "This is the content of the first post.",
"created_at": "2023-08-07T13:00:00Z",
"updated_at": "2023-08-07T13:00:00Z"
},
{
"id": 2,
"title": "Second Post",
"content": "This is the content of the second post.",
"created_at": "2023-08-08T10:00:00Z",
"updated_at": "2023-08-08T10:00:00Z"
}
]
}
データの整形
json: @model
を使用すると、モデルのすべての属性がJSONとして返されますが、この方法では不要な情報も含まれる可能性があります。例えば、ユーザーモデルにパスワードという属性がある場合、これはセキュリティ上の重要な情報ですが、Webアプリケーションが直接使用しない場合でも、パスワードが毎回JSONに含まれてしまいます。
また、date型やdatetime型の属性がある場合もJSONのフォーマットを指定することができません。
/*
json: @userの場合
- Userモデルのすべての属性を返すのでパスワードのような重要な情報も不要に返されてしまう
- datetime型データのフォーマットを指定できない
*/
{
"id": 1,
"name": "John Doe",
"password": "password",
"created_at": "2023-08-07T12:00:00Z",
"updated_at": "2023-08-07T12:00:00Z"
}
一方で ActiveModelSerializers
を使うと、返したい属性のみを返すことができますし、JSONのフォーマットを指定をすることもできます。
/*
ActiveModelSerializersの場合
- 返したい属性のみに絞ることができる
- datetime型データを日本語に変換することができる
*/
{
"id": 1,
"name": "John Doe",
"created_at": "2023年08月07日 12時00分00秒"
}