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

🔧 Nodeblocks Backend SDK

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


🧠 コア哲学

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

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

このアプローチは以下を提供します:

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

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

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

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

  2. Blocks – 純粋なビジネスロジック関数(例: createUser, findChatMessages)。Blocksは、再利用可能でテスト可能なビジネスロジックを含む基本的なビルディングブロックであり、組み合わせて使用するように設計されています。

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

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

  5. Featureschema + route(または複数のルート)のコンポジション。Featuresは関連する機能をまとめ、バリデーションルールと対応するエンドポイントを組み合わせます。

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

アーキテクチャ図

Backend Flow Schema

リクエストフロー

典型的なリクエストがレイヤードアーキテクチャをどのように流れるか:

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

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


🔧 コアコンセプト

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

Services

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

Composition

CompositionはSDKの中核となるパターンです。compose関数を使用すると、アプリケーションの異なる部分を左から右へ連鎖させることができます(右から左へ進む従来の関数コンポジションとは異なります)。シンプルな関数から始めて、徐々にそれらをより複雑なものに構築し、各関数はコンポジションチェーンに表示される順序で適用されます。

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

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

Primitives

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

withSchema

withSchemaプリミティブは、データバリデーション用のJSON Schemaを定義します。その強力さは、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およびWebSocketエンドポイントを定義します。プロトコル、HTTPメソッド(HTTPルートの場合)、パス、バリデーター、ハンドラー関数を指定する設定オブジェクトを受け取ります。

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

Features

Featureは、関連する機能の論理的なグループ化であり、通常は1つ以上のルートとそれに関連するスキーマで構成されます。その部分をコンポーズして機能を作成します。

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

⚡ クイックスタート

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

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


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

ハウツーガイド

一般的な開発タスクと高度なカスタマイズシナリオを段階的に説明するチュートリアル。

コンポーネント

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

組み込みサービス

すぐに使用できる共通機能を提供する、すぐに使えるサービスで、完全なカスタマイズオプションを備えています。


🙌 貢献

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