メインコンテンツまでスキップ
バージョン: 0.4.2

🧩 フィーチャー

フィーチャーは、スキーマと1つ以上のルートをグループ化する便利なラッパーです。サービスファクトリを簡潔に保ちながら、複雑な動作を構成できます。


1️⃣ 構造

フィーチャーはcompose関数を使用して構成されます。この関数は複数のコンポーネント(スキーマ、ルート、または他のフィーチャー)を受け取り、それらを単一の構成可能なユニットに結合します。このコンポジションパターンにより、シンプルで再利用可能な部品から複雑な機能を構築できます。

src/features/user.ts
import { compose } from '../primitives';
import { createUserSchema, updateUserSchema } from '../schemas/user';
import { createUserRoute, getUserRoute, findUsersRoute, updateUserRoute } from '../routes/user';

export const createUserFeature = compose(createUserSchema, createUserRoute);
export const getUserFeatures = compose(getUserRoute, findUsersRoute);
export const editUserFeatures = compose(updateUserSchema, updateUserRoute);

composeは任意の数の引数(スキーマ、ルート、さらには他のフィーチャー)を単一のComposableオブジェクトにフラット化し、サービスが消費できるようにします。コンポジションの順序は重要です - 通常、スキーマが最初に構成され、ルート実行前に検証が行われることを保証します。


2️⃣ フィーチャーを使用する理由

  • 再利用性 – 複数のサービス間で同じフィーチャーを共有
  • オーバーライド対応 – 下流アプリでフィーチャーを置換または拡張
  • 明確性 – フィーチャー内で低レベルの詳細を隠蔽

3️⃣ 良いプラクティス

  1. 単一責任 – 作成、読み取り、更新、削除で別々のフィーチャーを作成
  2. 一貫した命名<動詞><エンティティ>Feature(s)は発見を助ける
  3. スキーマを最初に構成 – 検証は常にルート実行に先立つべき

4️⃣ サービスでの使用

フィーチャーはdefService関数を通じてサービスに消費されます。この関数は、構成されたフィーチャーに必要なコンテキスト(データベース接続など)を提供します。Ramdaのpartial関数を使用してデータベース設定を事前適用し、Expressアプリケーションに簡単に統合できるサービスファクトリを作成します。

src/services/user.ts
import { compose, defService } from '../primitives';
import { partial } from 'lodash';
import { createUserFeature, getUserFeatures, editUserFeatures } from '../features/user';

export const userService = (db: any, configuration: any) =>
defService(
partial(
compose(editUserFeatures, getUserFeatures, createUserFeature),
{ dataStores: db, configuration }
)
);

このパターンにより、テスト、保守、拡張が容易なクリーンでモジュラーなサービスを作成できます。サービスファクトリパターンは、データベース接続やその他の依存関係がフィーチャーに適切に注入されることを保証します。


🎯 フィーチャーコンポジションの例

基本フィーチャー

// 単一操作フィーチャー
export const createUserFeature = compose(
createUserSchema,
createUserRoute
);

export const getUserFeature = compose(
getUserRoute
);

複合フィーチャー

// 複数操作を組み合わせたフィーチャー
export const userManagementFeature = compose(
createUserFeature,
getUserFeature,
updateUserFeature,
deleteUserFeature
);

高度なフィーチャー

// 認証を含む複雑なフィーチャー
export const authenticatedUserFeature = compose(
authenticationMiddleware,
userValidationSchema,
getUserByIdRoute,
userAccessValidation
);

📋 フィーチャーのベストプラクティス

1. 論理的なグループ化

関連する操作をまとめてグループ化:

// 良い - 関連操作のグループ化
export const userAccountFeatures = compose(
createAccountRoute,
activateAccountRoute,
deactivateAccountRoute
);

// 悪い - 無関係な操作の混在
export const mixedFeatures = compose(
createUserRoute,
sendEmailRoute,
generateReportRoute
);

2. 再利用可能な設計

// 再利用可能なベースフィーチャー
export const baseCrudFeature = (entitySchema, entityRoutes) =>
compose(entitySchema, ...entityRoutes);

// 特定エンティティ用の拡張
export const userCrudFeature = baseCrudFeature(userSchema, userRoutes);
export const productCrudFeature = baseCrudFeature(productSchema, productRoutes);

3. 明確な命名規則

// 一貫した命名パターン
export const createUserFeature = compose(/* ... */);
export const readUserFeature = compose(/* ... */);
export const updateUserFeature = compose(/* ... */);
export const deleteUserFeature = compose(/* ... */);

➡️ 次へ

サービスコンポーネントについて学習して、フィーチャーが完全なサービスにどのように構成されるかを理解しましょう。すべてのサービスは同じパターンと規約に従います!