1. はじめに
JavaScript のライブラリである normalizr の使い方を簡単に説明します。
2. normalizr とは?
normalizr とは、「JSONデータを正規化する」 ためのライブラリです。
「正規化」というのはデータベース用語なのですが、このライブラリに関しては以下のような意味合いを持つようです。
- 何らかの属性を持つデータは、全てマスター化する(そのため、データの階層はなくなる)。
- あるデータの中で他のデータを項目として持つ場合は、id によって参照させる。
3. 使い方ともう少し詳しい説明
paularmstrong/normalizr で、例として挙げられているデータ(JSON)を使ってもう少し詳しく説明します。
元となるデータ(JSON)
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
このデータ全体が1つの記事(article
)を表しており、以下の情報を持っています。
- この記事の
id
は、123 - この記事の著者(
author
)は、id
が 1の Paul さん - この記事のタイトル(
title
)は、”My awesome blog post” - この記事に対して書き込まれたコメント(
comments
)は 1件で、そのコメントは以下の情報を持っています。id
が324- コメントを書いた人(
commenter
)のid
は2 - コメントを書いた人(
commenter
)の名前は Nicole さん
この中で、著者(author
)とコメントを書いた人(commenter
)は、id
と name
を持ったユーザー(user
)であると考えられそうです。データベース的に考えると、ユーザー(user
)というマスターデータがあり、著者(author
)とコメントを書いた人(commenter
)を表すには、このマスターデータに登録されているユーザーの id
を指定すれば、データとして無駄がありません(重複がありません)。
また、id
と commenter
という項目を持つコメント(comments
)も、記事(article
)の中に丸ごと入れておくのではなく、独立したマスターデータとして存在させておいた方が無駄がありません。記事(article
)内では、保持するコメントの id
だけ指定しておけば関連していることが分かります。
ということで、無駄のない形でデータを持とうと思うと、
- ユーザーのデータ
- コメントのデータ
- 記事のデータ
をそれぞれマスターデータとして独立させ、関連する部分では id
だけ持たせておくというのが一番スッキリしています。これが normalizr の正規化です。
実際には、以下のようにこの 3つデータの Schema情報を定義して、データ構造の情報を補うことで正規化を実行することができます(Schema というのは「データの構造」といった意味になります)。
import { normalize, schema } from 'normalizr';
// (1) ユーザーを表すスキーマを定義します
const user = new schema.Entity('users');
// (2) コメントを表すスキーマを定義します
// - コメントの中には `commenter` という項目があり、それは先ほど定義した `user` がセットされます。
const comment = new schema.Entity('comments', {
commenter: user
});
// (3) 記事を表すスキーマを定義します
// - 記事には `author` という項目があり、それは `user` がセットされます。
// - 記事は `comments` という項目があり、それは先ほど定義した `comment` の配列になっています。
const article = new schema.Entity('articles', {
author: user,
comments: [ comment ]
});
// (4) このJSONデータ全体は、記事を表しているので `article` のスキーマで正規化します。
const normalizedData = normalize(originalData, article);
これにより、正規化されたJSONが生成されます。
正規化されたデータ(JSON)
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}
この変化を図にまとめました。
サーバーから取得したデータ(JSON)などは、必ずしも使いやすい形で得られるわけではないので、今回のように正規化することで、その中から欲しい情報をラクに取得することができるようになります。
4. 関連