🛠️ サービス
Nodeblocksバックエンドはモジュラーサービスで構成され、それぞれが特定のビジネスロジックとデータの部分を担当します。
すべてのサービスは同じ規約に従うため、統合、拡張、交換が簡単に行えます。
🔍 サービスとは何ですか?
サービスは、1つ以上のフィーチャー(ルート、スキーマ、ハンドラーを含むユースケースバンドル)を包む薄いラッパーです。
実行時にラッパーは依存関係(例:MongoDBコレクション)を配線し、コードから呼び出せる型付きインターフェースを公開または提供されたルーターユーティリティを通じてHTTPエンドポイントに自動的にマップします。
┌─────────────┐
│ Service │ userService(db)
├─────────────┤
│ Features ▷ createUserFeature
│ ▷ getUserFeatures
│ ▷ editUserFeatures
│ ▷ ...
└─────────────┘
重要なポイント:
- 純粋関数 – グローバル状態なし、すべての依存関係が明示的に渡される(テストに最適!)
- 構成可能 – サービス間でフィーチャーを再利用/構成するか、独自のものを構築
- データベース非依存 –
Collection
インターフェースのみが必要;テストでMongoをスタブに交換
📑 利用可能なサービス
サービス | NPMインポート | 責任 | ドキュメント |
---|---|---|---|
認証 | authService | ユーザー認証(登録、ログイン、ログアウト、JWTトークン) | ドキュメント » |
ユーザー | userService | アプリケーションユーザーの管理(CRUD、ロック/アンロック) | ドキュメント » |
組織 | organizationService | 組織/ワークスペースの作成と管理 | ドキュメント » |
商品 | productService | バッチとコピー操作を含む複雑な商品管理 | ドキュメント » |
カテゴリ | categoryService | 商品またはコンテンツカテゴリの維持 | ドキュメント » |
属性 | attributeService | キー値属性と属性グループの管理 | ドキュメント » |
注文 | orderService | 品目と価格設定を含むEコマース注文管理 | ドキュメント » |
チャット | chatService | チャンネル、サブスクリプション、メッセージによるリアルタイムメッセージング | ドキュメント » |
ℹ️ すべてのサービスは本番APIエンドポイントでテストされ、包括的なBrunoテストスイートが含まれています。時間をかけてSDKにさらなるサービスが追加されます。提案があればissueやPRを気軽に開いてください!
🧑💻 プログラム的なサービスの使用
すべてのサービスは同じ署名を共有します:名前付きコレクションとconfigを持つデータベースオブジェクトを受け取り、Expressルーターを返すファクトリ関数です。例外は認証サービスで、3番目のパラメータとしてメールクライアントも受け入れます。
import express from 'express';
import { MongoClient } from 'mongodb';
import { middlewares, services } from '@nodeblocks/backend-sdk';
const { nodeBlocksErrorMiddleware } = middlewares;
const { userService } = services;
const client = new MongoClient('mongodb://localhost:27017').db('dev');
express()
.use(
userService(
{
users: client.collection('users'),
identity: client.collection('identity'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running on http://localhost:8089'));
サービス設定パターン
すべてのサービスは一貫した設定パターンに従います:
// 基本パターン
const service = serviceFactory(
dataStores, // データベース接続
configuration // サービス設定
);
// 認証サービス(特別ケース)
const authService = authServiceFactory(
dataStores, // データベース接続
configuration, // サービス設定
mailClient // メール送信用
);
🏗️ カスタムサービスの作成
独自のサービスを作成することもできます:
import { compose, defService } from '@nodeblocks/backend-sdk';
import { partial } from 'lodash';
// フィーチャーを定義
const createItemFeature = compose(createItemSchema, createItemRoute);
const getItemFeature = compose(getItemRoute);
const updateItemFeature = compose(updateItemSchema, updateItemRoute);
// サービスファクトリを作成
export const customService = (dataStores: any, configuration: any) =>
defService(
partial(
compose(createItemFeature, getItemFeature, updateItemFeature),
{ dataStores, configuration }
)
);
カスタムサービスのベストプラクティス
- 一貫した命名:
<entity>Service
パターンを使用 - 設定分離: 設定オブジェクトを適切に分離
- エラーハンドリング: 常に
nodeBlocksErrorMiddleware
を含める - テスタビリティ: 依存関係注入パターンを使用
🔧 サービス統合
Express アプリケーションでの使用
import express from 'express';
import { services, middlewares } from '@nodeblocks/backend-sdk';
const app = express();
// 複数のサービスを統合
app.use('/api/auth', services.authService(db, config, mailClient));
app.use('/api/users', services.userService(db, config));
app.use('/api/products', services.productService(db, config));
// エラーミドルウェアは最後に
app.use(middlewares.nodeBlocksErrorMiddleware());
データベース設定
import { getMongoClient } from '@nodeblocks/backend-sdk';
const client = getMongoClient('mongodb://localhost:27017', 'myapp');
const dataStores = {
users: client.collection('users'),
identity: client.collection('identity'),
products: client.collection('products'),
orders: client.collection('orders')
};
設定管理
const configuration = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET,
authSignSecret: process.env.AUTH_SIGN_SECRET,
},
jwtOpts: {
expiresIn: '1h'
},
emailService: {
// メール設定
}
};
🎯 サービスのベストプラクティス
1. 依存関係注入
// 良い - 依存関係を明示的に注入
export const userService = (db: Database, config: Config) => {
return defService(/* ... */);
};
// 悪い - グローバル状態に依存
const globalDb = getDatabase();
export const userService = () => {
return defService(/* globalDbを使用 */);
};
2. エラーハンドリング
// 常にエラーミドルウェアを含める
app.use('/api', myService(db, config));
app.use(nodeBlocksErrorMiddleware()); // 必須!
3. 設定分離
// 良い - 環境別設定
const config = {
development: { /* dev設定 */ },
production: { /* prod設定 */ },
test: { /* test設定 */ }
}[process.env.NODE_ENV];
➡️ 次へ
具体的なサービスの実装について学習するには、個別のサービスドキュメント(認証サービス、ユーザーサービスなど)を参照してください!