データ構造の設計
サイズチャート機能では、大量のサイズチャートデータを管理し、商品情報から適切なチャートを高速に取得する必要があります。このページでは、データの構造と管理方法を解説します。
ファイル構成
サイズチャートのデータはJSONファイルとして管理しています。
ファイル構成
data/sizecharts/
サイズチャートデータの格納ディレクトリ
index.json
サイズチャート一覧
*.json
個別のサイズチャートデータ
ファイル命名規則
サイズチャートIDは以下の規則で命名しています。
| プレフィックス | カテゴリ | 例 |
|---|---|---|
| outer- | アウター | outer-men-jacket, outer-women-pants |
| ws- | ウィンタースポーツ | ws-men-jacket, ws-kids-jacket |
| cycling- | サイクリング | cycling-jacket, cycling-gloves |
outer-
カテゴリアウター
例outer-men-jacket, outer-women-pants
ws-
カテゴリウィンタースポーツ
例ws-men-jacket, ws-kids-jacket
cycling-
カテゴリサイクリング
例cycling-jacket, cycling-gloves
JSONファイルの構造
各サイズチャートJSONファイルには、表示用のHTMLテーブルと測定ガイドが含まれています。
{
"id": "outer-men-jacket",
"name": "アウター: ジャケット (メンズ)",
"category": "outerwear",
"itemType": "jacket",
"gender": "men",
"tableHtml": "<table>...</table>",
"measurementGuide": {
"chest": "胸囲: 胸の一番高い位置を水平に測定",
"height": "身長: 靴を脱いだ状態で測定"
}
}
正規化処理
Shopifyのメタフィールドには表記揺れが発生しやすいため、正規化処理を行います。
categoryの正規化
categoryの判定
入力値を小文字に変換
前処理
キーワードで判定
分類
ski, winter, snow を含む
→ winter-sports
bicycle, mtb, bike, cycling を含む
→ cycling
その他
→ outerwear(デフォルト)
genderの正規化
| 入力パターン | 正規化後 |
|---|---|
| women, woman, female, lady, レディース | women |
| kid, child, junior, キッズ | kids |
| men, man, male, メンズ | men |
| その他 | unisex |
women, woman, female, lady, レディース
正規化後women
kid, child, junior, キッズ
正規化後kids
men, man, male, メンズ
正規化後men
その他
正規化後unisex
マッピングデータの管理
マッピングは2箇所で管理し、柔軟性と安定性を両立しています。
マッピングデータの2層構造
lib/sizechart.ts
デフォルト値・フォールバック用
Vercel KV
管理画面からの動的変更用
優先順位
サイズチャート選択ロジック
KV → デフォルト値 の順で参照
なぜ2層構造なのか
- デフォルト値: コードに埋め込むことで、KV障害時もサービス継続可能
- Vercel KV: 管理画面から即座にマッピング変更可能
KVキーの設計
sizechart:mapping:{category}:{productType}:{gender}
→ サイズチャートID
sizechart:handle:{handle}
→ 専用サイズチャートID(Handle例外用)
sizechart:sku:{sku}
→ 専用サイズチャートID(SKU例外用)
例:
sizechart:mapping:outerwear:jackets:men→outer-men-jacketsizechart:handle:special-product-2024→special-product-chart
API設計
サイズチャートの取得はAPI経由で行います。
API呼び出しの流れ
商品ページ
クライアント
API呼び出し
/api/sizechart/get
選択ロジック実行
サーバー
JSONファイル読み込み
データ取得
レスポンス返却
サイズチャートデータ
APIリクエスト例
GET /api/sizechart/get
?handle=product-abc-001
&sku=ABC-001-M
&category=outerwear
&productType=jackets
&gender=men
APIレスポンス例
{
"success": true,
"chart": {
"id": "outer-men-jacket",
"name": "アウター: ジャケット (メンズ)",
"tableHtml": "<table>...</table>",
"measurementGuide": { ... }
}
}
キャッシュ戦略
サイズチャートデータは頻繁に変更されないため、積極的にキャッシュを活用しています。
| データ | キャッシュ場所 | 有効期間 |
|---|---|---|
| JSONファイル | サーバーメモリ | ビルド時に読み込み |
| マッピングデータ | Vercel KV | TTLなし(明示的に更新) |
| APIレスポンス | CDN Edge | 60秒(stale-while-revalidate) |
JSONファイル
キャッシュ場所サーバーメモリ
有効期間ビルド時に読み込み
マッピングデータ
キャッシュ場所Vercel KV
有効期間TTLなし(明示的に更新)
APIレスポンス
キャッシュ場所CDN Edge
有効期間60秒(stale-while-revalidate)
まとめ
サイズチャートのデータ構造は、以下のポイントで設計されています:
- JSONファイル管理: 大量のサイズチャートを静的ファイルとして管理
- 正規化処理: 表記揺れを吸収し、マッピング精度を向上
- 2層マッピング: デフォルト値とKVで柔軟性と安定性を両立
- キャッシュ活用: 高速なレスポンスを実現