BFF アーキテクチャ設計
本ドキュメントは、TASHIKA プラットフォームの BFF (Backend for Frontend) アーキテクチャ設計を定義します。
→ 採用決定の背景: ADR-004 React SPA + BFF アーキテクチャの採用
概要と設計判断
BFF の役割
BFF は ポータル特化の Presentation 層 であり、React SPA と Application 層の間に位置するデータ変換・集約・セキュリティ制御レイヤーである。
| 責務 | 説明 |
|---|---|
| ポータル別ビューモデル変換 | Application 層の Query/Command 結果を、従業員・管理者・代行事業者・システム各ポータルに最適化された形式に変換 |
| 認証・セッション管理 | BFF Proxy パターンによるトークンのサーバーサイド管理。ブラウザには HttpOnly Session Cookie のみ渡す |
| テナントコンテキスト解決 | セッションから TenantId / UserId を解決し、Application 層の MediatR ハンドラーに伝播 |
| キャッシュ制御 | TanStack Query との協調による Cache-Control ヘッダー戦略 |
| ファイルアップロード仲介 | マルチパートアップロードの受信、ウイルススキャン連携、署名付き URL 発行 |
アーキテクチャ上の位置づけ
重要な設計判断: in-process 呼び出し
BFF は Application 層を直接参照する(in-process)。バックエンド API への HTTP 呼び出しではない。
| 観点 | in-process(採用) | HTTP 呼び出し |
|---|---|---|
| レイテンシ | ゼロネットワークホップ | ループバック HTTP でも数ms のオーバーヘッド |
| MediatR 利用 | 直接 ISender.Send() を呼び出し | JSON シリアライズ/デシリアライズが必要 |
| 型安全性 | コンパイル時に Command/Query の型を検証 | OpenAPI スキーマ経由の間接的な型保証 |
| チーム構成 | 単一チーム開発に最適 | マイクロサービス分割の場合に有効 |
| 将来の分離 | MediatR のインターフェースが抽象化層として機能。HTTP 呼び出しへの切替が可能 | — |
Clean Architecture レイヤー図(更新版)
- BFF (Presentation): SPA からのリクエストを処理する Presentation 層。ポータル別ビューモデル変換を担う
- Backend Presentation: 外部連携 API を提供する Presentation 層。外部システム向けの汎用的なスキーマを採用
両者は同一の Application 層を参照するが、消費者(SPA vs 外部システム)に応じて異なるデータ形式・認証方式・レート制限を適用する。
→ 満たす要件: PE-001 パフォーマンス
プロジェクト構成
bff/ ディレクトリの内部構造
bff/
├── Endpoints/ -- Minimal API エンドポイント定義
│ ├── Employee/ -- 従業員ポータル向けエンドポイント
│ ├── Admin/ -- 管理者ポータル向けエンドポイント
│ ├── Agency/ -- 代行事業者ポータル向けエンドポイント
│ └── System/ -- システム管理向けエンドポイント
├── ViewModels/ -- ポータル別ビューモデル
│ ├── Employee/
│ ├── Admin/
│ ├── Agency/
│ └── System/
├── Transformers/ -- ポータル別データ変換ロジック
│ ├── IPortalTransformer.cs
│ └── Implementations/
├── Middleware/ -- BFF 固有のミドルウェア
│ ├── PortalContextMiddleware.cs
│ └── SessionAuthenticationMiddleware.cs
├── Auth/ -- BFF Proxy 認証
│ ├── SessionStore/
│ └── CsrfProtection/
├── OpenApi/ -- BFF OpenAPI 仕様管理
└── Program.cs -- ホスト構成・ミドルウェア登録依存関係
| プロジェクト | 参照先 | 目的 |
|---|---|---|
Tashika.Bff | Tashika.Application | MediatR Command/Query の送信 |
Tashika.Bff | Tashika.Domain | エンティティ・値オブジェクトの型利用(ViewModel 変換時) |
Tashika.Bff | Tashika.Infrastructure | DI 登録(EF Core、Cloud KMS 等のサービス解決) |
BFF は Application 層のインターフェース(ISender、IQuery<T> 等)を経由してビジネスロジックにアクセスする。Domain 層のエンティティを直接操作することはない。
Backend と BFF の共通/分離の境界
| 層 | 共通 | BFF 固有 | Backend 固有 |
|---|---|---|---|
| Domain | エンティティ、値オブジェクト | — | — |
| Application | Command/Query、バリデーション、ハンドラー | — | — |
| Infrastructure | EF Core、Cloud KMS、Storage | — | — |
| Presentation | — | ポータル別 ViewModel、セッション認証、CSRF | 外部 API エンドポイント、OAuth 2.0 |
| ミドルウェア | GlobalExceptionHandler、TraceId | PortalContext、SessionAuth | ExternalApiAuth |
サブページ
| ドキュメント | 内容 |
|---|---|
| リクエストパイプライン | ミドルウェア登録順序、ポータル別ビューモデル変換パターン |
| 認証アーキテクチャ | BFF Proxy パターン、セッション管理、CSRF 保護、SSO/OIDC 統合 |
| テナントコンテキスト・代理ログイン | テナントコンテキスト伝播、Impersonation フロー、データマスキング |
| キャッシュ・OpenAPI | TanStack Query 協調キャッシュ戦略、二層スキーマ管理 |
| 自動保存・ファイルアップロード | 自動保存エンドポイント設計、ファイルアップロード・ウイルススキャン |
| デプロイ方針 | MVP 単一サービスデプロイ、ヘルスチェック、将来のサービス分離 |