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

🔧 Nodeblocks Backend SDK

Nodeblocks Backend SDKは、堅牢で型安全なREST APIを数分で構築するための構成可能なユーティリティのコレクションです。
関数コンポジション依存性注入を中心に設計されており、すべてのレイヤーが分離してテストおよび再利用できます。


🧠 コア哲学

Nodeblocks Backend SDKは、バックエンドサービスに対する関数型、コンポジション型アプローチを採用しています。大規模で意見の分かれるフレームワークに依存する代わりに、小さく独立した関数とモジュールを組み合わせてアプリケーションを構築します。

SDKの中核となるアイデアは、複雑なシステムをシンプルで純粋な関数から構築できるということです。多くの状態とロジックを保持する大きなクラスやオブジェクトを作成するのではなく、小さく焦点を絞った関数を定義し、それらをより複雑な関数に組み合わせます。

このアプローチの利点:

  • モジュラリティ: アプリケーションの各部分は小さく自己完結型で、理解、テスト、再利用が容易です。
  • 宣言的スタイル: サービスを段階的に構築する方法を指定するのではなく、サービスが_何である_かを宣言します。
  • 予測可能性: 関数型原則の基盤により、システムの動作はより予測可能で推論しやすくなります。

🏗️ レイヤードアーキテクチャ

Nodeblocks Backend SDKは、各レイヤーが特定の責任を持ち、独立してコンポーズできる明確なレイヤードアーキテクチャに従います。この関心の分離により、コードがより保守可能、テスト可能、再利用可能になります。

  1. Schema – リクエスト検証のためのJSON-Schema定義。スキーマはデータの形状を定義し、受信リクエストを検証します。

  2. Handler – 非同期ビジネスロジック(例:createUser)。ハンドラーはコアアプリケーションロジックを含み、検証済み入力を受け取り結果またはエラーを返す純粋関数です。

  3. Route – HTTPメソッド + パス + ハンドラー + バリデーター。ルートはAPIエンドポイントを定義し、受け入れるHTTPメソッド、応答するパス、検証の適用方法を指定します。

  4. Featureスキーマ + ルート(または複数のルート)のコンポジション。フィーチャーは関連機能をバンドルし、検証ルールと対応するエンドポイントを組み合わせます。

  5. Service – 関連フィーチャーをグループ化し、外部依存関係(例:Mongo Collection)を配線します。サービスは複数のフィーチャーを組み合わせ、データベース接続などの依存関係を注入するトップレベルコンテナです。

アーキテクチャ図

Backend Flow Schema

リクエストフロー

典型的なリクエストがレイヤードアーキテクチャを通過する流れ:

Request → Route → Handler → DB / External API → Terminator → Response

各ユニットが純粋関数であるため、他のレイヤーに触れることなく任意のレイヤーを交換、装飾、拡張できます。


🔧 コア概念

レイヤードアーキテクチャを理解したところで、Nodeblocks Backend SDKを使用してアプリケーションを構築する際に使用する主要概念について詳しく見ていきましょう。これらの概念はAPIの構成要素を形成し、理解することで保守可能でスケーラブルなバックエンドサービスの作成に役立ちます。

サービス

サービスは、HTTPエンドポイントを提供するアプリケーションの構成可能な部分です。ExpressアプリケーションにマウントできるExpressミドルウェアとして実装されます。defService関数を使用してサービスを作成し、コンポーズされたフィーチャーセットと設定を受け取り、ミドルウェアとして使用準備の整ったExpressルーターを返します。

コンポジション

コンポジションはSDKの中心的なパターンです。compose関数を使用すると、アプリケーションの異なる部分を左から右へチェーンできます(右から左に進む従来の関数コンポジションとは異なります)。シンプルな関数から始めて、段階的により複雑な関数を構築し、各関数がコンポジションチェーンに現れる順序で適用されます。

// 複数のフィーチャーを単一のサービス定義にコンポーズ
const serviceDefinition = compose(feature1, feature2, feature3);

// コンポーズされた定義からサービスを作成
const service = defService(partial(serviceDefinition, [...]));

プリミティブ

プリミティブは、サービス用のブロックを構築するのに役立つ低レベルヘルパー関数です。最も一般的に使用される2つのプリミティブはwithSchemawithRouteです。

withSchema

withSchemaプリミティブはデータ検証用のJSONスキーマを定義します。強力な点はwithRouteとの相互作用です - withSchemaをコンポーズすると、次のルートの検証が自動的に設定されます。

// 再利用可能なスキーマを定義
const userSchema: SchemaDefinition = {
$schema: 'http://json-schema.org/draft-07/schema#',
additionalProperties: false,
properties: {
email: { type: 'string' },
name: { type: 'string' },
status: { type: 'string' },
},
type: 'object',
};

export const createUserSchema = withSchema({
requestBody: {
content: {
'application/json': {
schema: {
...userSchema,
required: ['email', 'name', 'status'],
},
},
},
required: true,
},
});

// 同じスキーマを複数のルートに適用
const createUserFeature = compose(createUserSchema, createUserRoute);
const updateUserFeature = compose(createUserSchema, updateUserRoute);

withRoute

withRouteプリミティブはHTTPエンドポイントを定義します。HTTPメソッド、パス、バリデーター、ハンドラー関数を指定する設定オブジェクトを受け取ります。

const createUserRoute = withRoute({
handler: compose(
withLogging(createUser),
flatMapAsync(withLogging(getUserById)),
lift(withLogging(normalizeUserTerminator))
),
method: 'POST',
path: '/users',
validators: [verifyAuthentication(getBearerTokenInfo)],
});

フィーチャー

フィーチャーは、通常1つまたは複数のルートとその関連スキーマで構成される、関連機能の論理的グループです。部品をコンポーズしてフィーチャーを作成します。

// スキーマとルートをコンポーズして完全なフィーチャーを作成
export const userFeature = compose(createUserSchema, createUserRoute);

⚡ クイックスタート

最初のAPIを素早く立ち上げたいですか?インストール、サーバーブートストラップ、最初のリクエストのテストを順を追って説明するクイックスタートチュートリアルに従ってください。

クイックスタートチュートリアルを開く →


📑 利用可能なドキュメント

ハウツーガイド

一般的な開発タスクと高度なカスタマイゼーションシナリオを順を追って説明するチュートリアル。

コンポーネント

APIリファレンス、使用パターン、ベストプラクティスを含む各アーキテクチャコンポーネントの詳細説明。

組み込みサービス

完全なカスタマイゼーションオプション付きで、一般的な機能をすぐに使用できる既製のサービス。


🙌 貢献

バグを見つけたりアイデアがありますか?GitHubでissueやPRを開いてください - 貢献を歓迎します。