メインコンテンツまでスキップ
バージョン: 0.5.0 (最新)

🏷️ 属性サービス

Testing Status

属性サービスは、キーと値のペアからなる属性グループを管理するための完全な REST API を提供します。Nodeblocks の関数型合成アプローチと MongoDB 連携により、製品の属性、カテゴリのプロパティ、その他の構造化メタデータを扱えるよう設計されています。


🚀 クイックスタート

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

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

const client = getMongoClient('mongodb://localhost:27017', 'dev');

express()
.use(
attributesService(
{
attributes: client.collection('attributes'),
identities: client.collection('identities'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
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 ヘッダーが必須です。欠如している場合、リクエストは 401 Unauthorized を返します。


🔧 API Endpoints

1. 属性グループの作成

指定された名前とキー・値ペアで新しい属性グループを作成します。

リクエスト:

  • Method: POST
  • Path: /attributes
  • ヘッダー:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: 管理者ロール必須

リクエストボディ:

フィールド必須説明
namestring属性グループ名
itemsarrayキー・値ペアの配列(最低1件)
items[].keystring属性キー/名称
items[].valuestring属性値

レスポンスボディ:

フィールド説明
namestring属性グループ名
itemsarrayキー・値ペアの配列
items[].keystring属性キー/名称
items[].valuestring属性値
createdAtstring作成日時
idstring属性グループの一意ID
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: 自動適用(name と items が必須、追加プロパティ不可)

  • ルートバリデーション:

    • 認証済みリクエスト(ベアラートークン)必須
    • 管理者ロール必須
  • 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": "Product Specifications",
"items": [
{
"key": "Color",
"value": "Blue"
},
{
"key": "Size",
"value": "Large"
},
{
"key": "Material",
"value": "Cotton"
}
]
}'

成功レスポンス:

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

{
"name": "Product Specifications",
"items": [
{
"key": "Color",
"value": "Blue"
},
{
"key": "Size",
"value": "Large"
},
{
"key": "Material",
"value": "Cotton"
}
],
"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": "Validation Error",
"data": [
"request body must have required property 'items'"
]
}
}

items 配列が空の場合:

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

{
"error": {
"message": "Validation Error",
"data": [
"request body must NOT have fewer than 1 items"
]
}
}

認証に失敗した場合:

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

{
"error": {
"message": "Authentication failed"
}
}

2. 属性グループの取得(ID指定)

一意IDで特定の属性グループを取得します。

リクエスト:

  • Method: GET
  • Path: /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": "Product Specifications",
"items": [
{
"key": "Color",
"value": "Blue"
},
{
"key": "Size",
"value": "Large"
},
{
"key": "Material",
"value": "Cotton"
}
],
"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": "Attribute group not found"
}
}

3. 属性グループ一覧

属性グループをフィルタ/ページング付きで一覧取得します。

リクエスト:

  • Method: GET
  • Path: /attributes
  • ヘッダー: なし
  • 認可: 不要

クエリパラメータ:

パラメータ必須説明
namestring属性グループ名でフィルタ
pagenumberページ番号
limitnumber1ページあたりの件数

レスポンスボディ:

フィールド説明
namestring属性グループ名
itemsarrayキー・値ペアの配列
items[].keystring属性キー/名称
items[].valuestring属性値
createdAtstring作成日時
idstring属性グループの一意ID
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: name とページング(page, limit)のクエリ検証
  • ルートバリデーション: なし

リクエスト例:

すべての属性グループを一覧:

curl {{host}}/attributes

name でフィルタ:

curl "{{host}}/attributes?name=Product"

Success Response:

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

[
{
"name": "Product Specifications",
"items": [
{
"key": "Color",
"value": "Blue"
},
{
"key": "Size",
"value": "Large"
}
],
"createdAt": "2025-07-07T08:52:49.796Z",
"id": "69b013c9-cb20-4a7e-9c1f-59a55db1d949",
"updatedAt": "2025-07-07T08:52:49.796Z"
},
{
"name": "Technical Details",
"items": [
{
"key": "Weight",
"value": "2.5kg"
},
{
"key": "Dimensions",
"value": "30x20x15cm"
}
],
"createdAt": "2025-07-07T08:20:45.456Z",
"id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
"updatedAt": "2025-07-07T08:20:45.456Z"
}
]

4. 属性グループの更新

既存の属性グループを更新します。注意: スキーマ上、更新できるのは name フィールドのみです。items 配列はこの更新エンドポイントでは変更できません。

リクエスト:

  • Method: PATCH
  • Path: /attributes/:attributeId
  • ヘッダー:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: 管理者ロール必須

URL パラメータ:

パラメータ必須説明
attributeIdstring属性グループの一意ID

リクエストボディ:

フィールド必須説明
namestring新しい属性グループ名

レスポンスボディ:

フィールド説明
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": "Updated Product Specifications"}'

成功レスポンス:

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

{
"name": "Updated Product Specifications",
"items": [
{
"key": "Color",
"value": "Blue"
},
{
"key": "Size",
"value": "Large"
},
{
"key": "Material",
"value": "Cotton"
}
],
"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": "Attribute group not found"
}
}

認証に失敗した場合:

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

{
"error": {
"message": "Authentication failed"
}
}

5. 属性グループの削除

システムから属性グループを完全に削除します。

リクエスト:

  • Method: DELETE
  • Path: /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": "Attribute group not found"
}
}

認証に失敗した場合:

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

{
"error": {
"message": "Authentication failed"
}
}

⚙️ 設定オプション

サービス設定

interface AttributesServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
identity?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
regular: string; // Regular user type identifier
};
};
}

設定詳細

属性サービスの設定は、セキュリティとユーザー種別管理の論理グループに整理されています。

🔐 セキュリティ設定

authSecrets - JWT token security secrets

  • Type: { authEncSecret: string; authSignSecret: string }
  • Description: Secret keys for JWT encryption and signing (used for token validation)
  • Required: Yes (for production)
  • Child Properties:
    • authEncSecret: Secret key for JWT payload encryption
    • authSignSecret: Secret key for JWT signature verification

👥 ユーザー種別設定

user.typeIds - ユーザー種別識別子の設定

  • : { admin?: string; guest?: string; user?: string }
  • 説明: ロールベースアクセス制御のためのカスタム種別識別子
  • 既定: undefined(既定の種別検証を使用)
  • 子プロパティ:
    • admin: 管理者ユーザーの種別識別子
      • : string
      • 説明: 管理者ユーザー向けのカスタム識別子
      • 用途: 管理操作に対するロールベースアクセス制御
      • : "admin", "administrator", "superuser"
    • guest: ゲストユーザーの種別識別子
      • : string
      • 説明: ゲストユーザー向けのカスタム識別子
      • 用途: 非認証または一時ユーザーの限定アクセス
      • : "guest", "visitor", "anonymous"
    • user: 一般ユーザーの種別識別子
      • : 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'
},
user: {
typeIds: {
admin: 'administrator',
guest: 'visitor',
user: 'member'
}
}
};

🚨 エラーハンドリング

属性サービスのエラーは、適切なHTTPステータスコードとJSON形式で返されます:

代表的なエラーコード

ステータスエラーメッセージ説明
400Validation Errorリクエストボディの形式不正または必須項目不足
400request body must have required property 'name'リクエストボディに name が存在しない
400request body must have required property 'items'リクエストボディに items が存在しない
400request body must NOT have fewer than 1 itemsitems 配列が空(最低1件が必要)
400request body must NOT have additional propertiesサポートされないフィールドが含まれている
400Failed to create attribute追加IDが返らず作成に失敗
400Failed to update attribute更新対象の変更が検出されず失敗
401Authentication failed認証トークンがない/無効
401token could not be verified認可トークンがない/無効
403User is not authorized to access this resource必要な権限が不足(管理者アクセス)
404Attribute group not found対象の属性グループが存在しない
500Failed to create attribute作成中のDB接続問題/予期せぬ失敗
500Failed to get attribute取得中のDB接続問題/予期せぬ失敗
500Failed to find attributes一覧取得中のDB接続問題/フィルタ不正/予期せぬ失敗
500Failed to update attribute更新中のDB接続問題/予期せぬ失敗
500Failed to delete attribute削除中のDB接続問題/予期せぬ失敗

エラーレスポンス形式

{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}

Validation Errors には追加情報が含まれます:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'items'",
"request body must NOT have fewer than 1 items"
]
}
}

🔗 関連ドキュメント