メむンコンテンツたでスキップ
バヌゞョン: 0.13.0 (Previous)

🏷 属性サヌビス

テストステヌタス

属性サヌビス (attributesService) は、キヌバリュヌペアによる属性グルヌプの管理ための完党な REST API を提䟛したす。Nodeblocks の関数型コンポゞションアプロヌチず MongoDB 統合を䜿甚しお、商品属性、カテゎリプロパティ、およびその他の構造化メタデヌタを凊理するように蚭蚈されおいたす。


🚀 クむックスタヌト​

import express from 'express';
import {middlewares, services, drivers} from '@nodeblocks/backend-sdk';

const {nodeBlocksErrorMiddleware} = middlewares;
const {attributesService} = services;
const {withMongo} = drivers;

const connectToDatabase = withMongo('mongodb://localhost:27017/?authSource=admin', 'dev', 'user', 'password');

express()
.use(
attributesService(
{
...(await connectToDatabase('attributes')),
...(await connectToDatabase('identities')),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
authMode: 'bearer', // たたは 'cookie'
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001',
},
},
},
),
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 ゚ンドポむント䞀芧​

属性グルヌプ操䜜​

メ゜ッドパス説明認蚌必芁
POST/attributes新しい属性グルヌプを䜜成✅ 管理者
GET/attributes/:attributeIdID で属性グルヌプを取埗❌ なし
GET/attributes属性グルヌプの䞀芧/フィルタ❌ なし
PATCH/attributes/:attributeId属性グルヌプを曎新✅ 管理者
DELETE/attributes/:attributeId属性グルヌプを削陀✅ 管理者

🗄 ゚ンティティスキヌマ​

属性グルヌプ゚ンティティは、基本フィヌルド自動生成ᅵᅵᅵ属性固有のデヌタを組み合わせたす:

{
"name": "string",
"items": [
{
"key": "string",
"value": "string"
}
],
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

フィヌルド詳现​

フィヌルドタむプ自動生成必須説明
namestring❌✅属性グルヌプ名
itemsarray❌✅キヌバリュヌペアの配列最小1項目
items[].keystring❌✅属性キヌ/名前
items[].valuestring❌✅属性倀
createdAtdatetime✅✅䜜成タむムスタンプ
idstring✅✅ナニヌク識別子UUID
updatedAtdatetime✅✅最終曎新タむムスタンプ

📝 泚: 自動生成フィヌルドはサヌビスによっお蚭定され、䜜成/曎新リク゚ストに含たれおいおはなりたせん。items 配列には少なくずも1぀のキヌバリュヌペアを含める必芁がありたす。


🔐 認蚌ヘッダヌ​

ベアラヌ認蚌のリク゚ストには、以䞋のヘッダヌを含めおください:

Authorization: Bearer <admin_access_token>
x-nb-fingerprint: <device_fingerprint>

⚠ 重芁: x-nb-fingerprint ヘッダヌは、認蚌時にフィンガヌプリントが指定された堎合、ベアラヌ認蚌リク゚ストに必須です。クッキヌモヌドでは、アクセストヌクンは Authorization ヘッダヌではなく accessToken クッキヌから読み取られたす。


🔧 API ゚ンドポむント​

1. 属性グルヌプの䜜成​

提䟛された名前ずキヌバリュヌペアで新しい属性グルヌプを䜜成したす。

リク゚スト:

  • メ゜ッド: POST
  • パス: /attributes
  • ヘッダヌ:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認蚌: 管理者ロヌルが必芁

リク゚ストボディ:

フィヌルドタむプ必須説明
namestring✅属性グルヌプ名
itemsarray✅キヌバリュヌペアの配列
items[].keystring✅属性キヌ/名前
items[].valuestring✅属性倀

レスポンスボディ:

フィヌルドタむプ説明
namestring属性グルヌプ名
itemsarrayキヌバリュヌペアの配列
items[].keystring属性キヌ/名前
items[].valuestring属性倀
createdAtstring䜜成タむムスタンプ
idstringナニヌクな属性グルヌプID
updatedAtstring最終曎新タむムスタンプ

バリデヌション:

  • スキヌマバリデヌション: 自動的に適甚name, items 必須、远加プロパティ䞍可
  • ルヌトバリデヌタ:
    • 認蚌枈みリク゚ストを芁求ベアラヌトヌクン
    • 管理者ロヌルを芁求

アむテムバリデヌション: 少なくずも1぀のアむテムを含み、それぞれに必須の key ず value が必芁です。

䟋リク゚スト:

curl -X POST {{host}}/attributes \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin_token>" \
-H "x-nb-fingerprint: test-device-fingerprint" \
-d '{
"name": "商品仕様",
"items": [
{
"key": "色",
"value": "青"
},
{
"key": "サむズ",
"value": "倧"
},
{
"key": "玠材",
"value": "ç¶¿"
}
]
}'

成功レスポンス:

HTTP/1.1 201 Created
Content-Type: application/json

{
"name": "商品仕様",
"items": [
{
"key": "色",
"value": "青"
},
{
"key": "サむズ",
"value": "倧"
},
{
"key": "玠材",
"value": "ç¶¿"
}
],
"createdAt": "2025-07-07T08:52:49.796Z",
"id": "69b013c9-cb20-4a7e-9c1f-59a55db1d949",
"updatedAt": "2025-07-07T08:52:49.796Z"
}

゚ラヌレスポンス:

必須フィヌルドが欠萜しおいる堎合:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "バリデヌション゚ラヌ",
"data": [
"リク゚ストボディに必須プロパティ 'items' がありたせん"
]
}
}

アむテム配列が空の堎合:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "バリデヌション゚ラヌ",
"data": [
"リク゚ストボディは1個以䞊のアむテムを持぀必芁がありたす"
]
}
}

認蚌が倱敗した堎合:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "トヌクンを怜蚌できたせんでした"
}
}

2. ID で属性グルヌプを取埗​

䞀意の ID によっお特定の属性グルヌプを取埗したす。

リク゚スト:

  • メ゜ッド: GET
  • パス: /attributes/:attributeId
  • ヘッダヌ: なし
  • 認蚌: 䞍芁

URL パラメヌタ:

パラメヌタタむプ必須説明
attributeIdstring✅ナニヌクな属性グルヌプID

レスポンスボディ:

フィヌルドタむプ説明
namestring属性グルヌプ名
itemsarrayキヌバリュヌペアの配列
items[].keystring属性キヌ/名前
items[].valuestring属性倀
createdAtstring䜜成タむムスタンプ
idstringナニヌクな属性グルヌプID
updatedAtstring最終曎新タむムスタンプ

バリデヌション:

  • スキヌマバリデヌション: パスパラメヌタの attributeId でバリデヌション
  • ルヌトバリデヌタ: なし

䟋リク゚スト:

curl {{host}}/attributes/69b013c9-cb20-4a7e-9c1f-59a55db1d949

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"name": "商品仕様",
"items": [
{
"key": "色",
"value": "青"
},
{
"key": "サむズ",
"value": "倧"
},
{
"key": "玠材",
"value": "ç¶¿"
}
],
"createdAt": "2025-07-07T08:52:49.796Z",
"id": "69b013c9-cb20-4a7e-9c1f-59a55db1d949",
"updatedAt": "2025-07-07T08:52:49.796Z"
}

゚ラヌレスポンス:

指定された ID の属性グルヌプが存圚しない堎合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "属性グルヌプが芋぀かりたせん"
}
}

3. 属性グルヌプの䞀芧​

オプションのフィルタずペヌゞネヌションで属性グルヌプの䞀芧を取埗したす。

リク゚スト:

  • メ゜ッド: GET
  • パス: /attributes
  • ヘッダヌ: なし
  • 認蚌: 䞍芁

ク゚リパラメヌタ:

パラメヌタタむプ必須説明
namestring❌属性グルヌプ名でフィルタ
pagenumber❌ペヌゞネヌションのペヌゞ番号1-1000
limitnumber❌ペヌゞあたりのアむテム数1-50

レスポンスボディ: 属性グルヌプ配列ずメタデヌタを含むペヌゞネヌションレスポンス。

レスポンス構造:

{
"data": [
{
"name": "string",
"items": [
{
"key": "string",
"value": "string"
}
],
"createdAt": "string",
"id": "string",
"updatedAt": "string"
}
],
"metadata": {
"pagination": {
"page": number,
"limit": number,
"total": number,
"totalPages": number,
"hasNext": boolean,
"hasPrev": boolean
}
}
}

バリデヌション:

  • スキヌマバリデヌション: ク゚リパラメヌタの name ずペヌゞネヌションpage, limitでバリデヌション
  • ルヌトバリデヌタ: なし

䟋リク゚スト:

すべおの属性グルヌプを䞀芧:

curl {{host}}/attributes

名前でフィルタ:

curl "{{host}}/attributes?name=商品"

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"data": [
{
"name": "商品仕様",
"items": [
{
"key": "色",
"value": "青"
},
{
"key": "サむズ",
"value": "倧"
}
],
"createdAt": "2025-07-07T08:52:49.796Z",
"id": "69b013c9-cb20-4a7e-9c1f-59a55db1d949",
"updatedAt": "2025-07-07T08:52:49.796Z"
},
{
"name": "技術詳现",
"items": [
{
"key": "重量",
"value": "2.5kg"
},
{
"key": "寞法",
"value": "30x20x15cm"
}
],
"createdAt": "2025-07-07T08:20:45.456Z",
"id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"updatedAt": "2025-07-07T08:20:45.456Z"
}
],
"metadata": {
"pagination": {
"page": 1,
"limit": 10,
"total": 2,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}
}

ペヌゞネヌション䟋リク゚スト:

curl "{{host}}/attributes?page=1&limit=10"

4. 属性グルヌプの曎新​

既存の属性グルヌプを曎新したす。泚: スキヌマによるず、name フィヌルドのみが曎新可胜です — items 配列は曎新゚ンドポむントを通じお倉曎できたせん。

リク゚スト:

  • メ゜ッド: PATCH
  • パス: /attributes/:attributeId
  • ヘッダヌ:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認蚌: 管理者ロヌルが必芁

URL パラメヌタ:

パラメヌタタむプ必須説明
attributeIdstring✅ナニヌクな属性グルヌプID

リク゚ストボディ:

フィヌルドタむプ必須説明
namestring❌新しい属性グルヌプ名

JSON ボディは存圚し空であっおはなりたせん。名前がスキヌマでオプションでも、空のボディ {} たたは欠萜したボディは "リク゚ストボディが必芁です" で 400 を返したす。

レスポンスボディ:

フィヌルドタむプ説明
namestring曎新された属性グルヌプ名
itemsarrayキヌバリュヌペアの配列倉曎なし
items[].keystring属性キヌ/名前
items[].valuestring属性倀
createdAtstring䜜成タむムスタンプ
idstringナニヌクな属性グルヌプID
updatedAtstring最終曎新タむムスタンプ

バリデヌション:

  • スキヌマバリデヌション: 自動的に適甚name フィヌルドのみ蚱可、远加プロパティ䞍可
  • ルヌトバリデヌタ:
    • 認蚌枈みリク゚ストを芁求ベアラヌトヌクン
    • 管理者ロヌルを芁求

⚠ 重芁: 曎新スキヌマは name フィヌルドの曎新のみを蚱可したす。items 配列を倉曎するには、属性グルヌプを削陀しお再生成する必芁がありたす。

䟋リク゚スト:

curl -X PATCH {{host}}/attributes/69b013c9-cb20-4a7e-9c1f-59a55db1d949 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin_token>" \
-H "x-nb-fingerprint: test-device-fingerprint" \
-d '{"name": "曎新された商品仕様"}'

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"name": "曎新された商品仕様",
"items": [
{
"key": "色",
"value": "青"
},
{
"key": "サむズ",
"value": "倧"
},
{
"key": "玠材",
"value": "ç¶¿"
}
],
"createdAt": "2025-07-07T08:52:49.796Z",
"id": "69b013c9-cb20-4a7e-9c1f-59a55db1d949",
"updatedAt": "2025-07-07T08:54:07.406Z"
}

゚ラヌレスポンス:

指定された ID の属性グルヌプが存圚しない堎合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "属性グルヌプが芋぀かりたせん"
}
}

認蚌が倱敗した堎合:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "トヌクンを怜蚌できたせんでした"
}
}

5. 属性グルヌプの削陀​

属性グルヌプをシステムから完党に削陀したす。

リク゚スト:

  • メ゜ッド: DELETE
  • パス: /attributes/:attributeId
  • ヘッダヌ:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認蚌: 管理者ロヌルが必芁

URL パラメヌタ:

パラメヌタタむプ必須説明
attributeIdstring✅ナニヌクな属性グルヌプID

レスポンスボディ:

フィヌルドタむプ説明
レスポンスボディなし-削陀゚ンドポむントは成功時にレスポンスボディを返したせん

バリデヌション:

  • スキヌマバリデヌション: パスパラメヌタの attributeId でバリデヌション
  • ルヌトバリデヌタ:
    • 認蚌枈みリク゚ストを芁求ベアラヌトヌクン
    • 管理者ロヌルを芁求

䟋リク゚スト:

curl -X DELETE {{host}}/attributes/69b013c9-cb20-4a7e-9c1f-59a55db1d949 \
-H "Authorization: Bearer <admin_token>" \
-H "x-nb-fingerprint: test-device-fingerprint"

成功レスポンス:

HTTP/1.1 204 No Content

゚ラヌレスポンス:

指定された ID の属性グルヌプが存圚しない堎合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "属性が芋぀かりたせん"
}
}

認蚌が倱敗した堎合:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "トヌクンを怜蚌できたせんでした"
}
}

⚙ 蚭定オプション​

サヌビスデヌタストア​

interface AttributesServiceDataStore {
attributes: Collection; // 必須 - 属性グルヌプコレクション
identities: Collection; // 必須 - 認蚌コンテキスト甚アむデンティティ
}

サヌビス蚭定​

interface AttributesServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT 暗号化シヌクレット
authSignSecret: string; // JWT 眲名シヌクレット
};
authMode?: 'bearer' | 'cookie'; // デフォルト: 未蚭定の堎合ベアラヌ動䜜
identity?: {
typeIds?: {
admin: string; // 管理者ナヌザヌタむプ識別子
guest: string; // ゲストナヌザヌタむプ識別子
regular: string; // 䞀般ナヌザヌタむプ識別子
};
};
}

蚭定詳现​

属性サヌビス蚭定は、セキュリティずナヌザヌタむプ管理の論理グルヌプに敎理されおいたす。

🔐 セキュリティ蚭定​

authSecrets — JWT トヌクンセキュリティシヌクレット

  • タむプ: { authEncSecret: string; authSignSecret: string }
  • 説明: JWT 暗号化ず眲名甚のシヌクレットキヌトヌクン怜蚌に䜿甚
  • 必須: はい本番甚
  • 子プロパティ:
    • authEncSecret: JWT ペむロヌド暗号化甚のシヌクレットキヌ
    • authSignSecret: JWT 眲名怜蚌甚のシヌクレットキヌ

👥 ナヌザヌタむプ蚭定​

identity.typeIds — ナヌザヌタむプ識別子蚭定

  • タむプ: { admin: string; guest: string; regular: string }
  • 説明: ロヌルベヌスアクセス制埡甚のカスタムナヌザヌタむプ識別子
  • デフォルト: undefinedオブゞェクトはオプションですが、存圚する堎合 checkIdentityType は3぀のキヌすべおを芁求したす
  • 子プロパティ:
    • admin: 管理者ナヌザヌタむプ識別子
      • タむプ: string
      • 説明: 管理者ナヌザヌ甚のカスタム識別子
      • ナヌスケヌス: 管理操䜜のロヌルベヌスアクセス制埡
      • 䟋: "admin", "administrator", "superuser"
    • guest: ゲストナヌザヌタむプ識別子
      • タむプ: string
      • 説明: ゲストナヌザヌ甚のカスタム識別子
      • ナヌスケヌス: 認蚌枈みたたは䞀時的なナヌザヌの制限付きアクセス
      • 䟋: "guest", "visitor", "anonymous"
    • regular: 䞀般ナヌザヌタむプ識別子
      • タむプ: string
      • 説明: 䞀般ナヌザヌ甚のカスタム識別子
      • ナヌスケヌス: 暙準ナヌザヌアクセス暩限
      • 䟋: "user", "member", "customer"

䟋蚭定​

const attributesConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret',
},
identity: {
typeIds: {
admin: 'administrator',
guest: 'visitor',
regular: 'member',
},
},
};

🚚 ゚ラヌハンドリング​

すべおの属性サヌビス゚ラヌは適切な HTTP ステヌタスコヌドで JSON フォヌマットで返されたす:

䞀般的な゚ラヌコヌド​

ステヌタス゚ラヌメッセヌゞ説明
400バリデヌション゚ラヌリク゚ストボディのフォヌマットが無効たたは必須フィヌルドが欠萜
400リク゚ストボディに必須プロパティ 'name' がありたせんリク゚ストボディに name フィヌルドが欠萜
400リク゚ストボディに必須プロパティ 'items' がありたせんリク゚ストボディに items 配列が欠萜
400リク゚ストボディは1個以䞊のアむテムを持぀必芁がありたすアむテム配列が空最小1項目必芁
400リク゚ストボディは远加プロパティを持っおはいけたせんリク゚ストにサポヌトされおいないフィヌルドが含たれおいたす
400属性グルヌプの䜜成に倱敗したしたデヌタベヌス挿入操䜜が挿入IDを返さない
400属性グルヌプの曎新に倱敗したした曎新操䜜がデヌタを倉曎しない倉曎なし怜出
401トヌクンを怜蚌できたせんでした欠萜たたは無効な認蚌トヌクン
401無効なトヌクンcheckIdentityType でのナヌザヌアクセストヌクン怜蚌でトヌクンが倱敗
403アむデンティティはこのリ゜ヌスにアクセスする暩限がありたせんアむデンティティに必芁なタむプの暩限がありたせん管理者アクセス
404属性が芋぀かりたせん芁求された操䜜に察しお属性グルヌプが存圚しない
500属性グルヌプの䜜成䞭に䞍明な゚ラヌデヌタベヌス接続問題たたは䜜成䞭の予期せぬ倱敗
500属性グルヌプの取埗に倱敗したしたデヌタベヌス接続問題たたは取埗䞭の予期せぬ倱敗
500属性の怜玢に倱敗したしたデヌタベヌス接続問題、無効なフィルタヌ構文、たたは䞀芧䞭の予期せぬ倱敗
500属性グルヌプの曎新に倱敗したしたデヌタベヌス接続問題たたは曎新䞭の予期せぬ倱敗
500属性の削陀に倱敗したしたデヌタベヌス接続問題たたは削陀䞭の予期せぬ倱敗

゚ラヌレスポンスフォヌマット​

{
"error": {
"message": "゚ラヌメッセヌゞの説明",
"data": ["远加の゚ラヌ詳现"]
}
}

バリデヌション゚ラヌ は远加詳现を含みたす:

{
"error": {
"message": "バリデヌション゚ラヌ",
"data": [
"リク゚ストボディに必須プロパティ 'name' がありたせん",
"リク゚ストボディに必須プロパティ 'items' がありたせん",
"リク゚ストボディは1個以䞊のアむテムを持぀必芁がありたす"
]
}
}

🔗 関連ドキュメント​