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

🔧 Nodeblocks Backend SDK

The Nodeblocks Backend SDK is a collection of composable utilities for building robust, type-safe REST APIs in minutes.
It is designed around functional composition & dependency injection so that every layer can be tested and reused in isolation.


🧠 Core Philosophy

The Nodeblocks Backend SDK embraces a functional, compositional approach to backend services. Instead of relying on large, opinionated frameworks, you construct your application by composing small, independent functions and modules.

At the heart of the SDK is the idea that complex systems can be built from simple, pure functions. Rather than creating large classes or objects that hold a lot of state and logic, you define small, focused functions and compose them into more complex ones.

This approach provides:

  • Modularity: Each piece of your application is small and self-contained, making it easy to understand, test, and reuse.
  • Declarative Style: You declare what your service is, rather than specifying how it should be built step-by-step.
  • Predictability: With a foundation in functional principles, the behavior of your system is more predictable and easier to reason about.

🏗️ Layered Architecture

The Nodeblocks Backend SDK follows a clear layered architecture where each layer has a specific responsibility and can be composed independently. This separation of concerns makes your code more maintainable, testable, and reusable.

  1. Schema – JSON-Schema definitions for request validation. Schemas define the shape of your data and validate incoming requests.

  2. Handler – The async business logic (e.g. createUser). Handlers contain your core application logic and are pure functions that take validated input and return results or errors.

  3. Route – HTTP method + path + handler + validators. Routes define your API endpoints and specify which HTTP methods they accept, what path they respond to, and how validation should be applied.

  4. Feature – Composition of a schema + route (or multiple routes). Features bundle related functionality together, combining validation rules with their corresponding endpoints.

  5. Service – Groups related features and wires external deps (e.g. Mongo Collection). Services are the top-level containers that combine multiple features and inject dependencies like database connections.

Architecture diagram

Backend Flow Schema

Request Flow

Here's how a typical request flows through the layered architecture:

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

Because each unit is a pure function you can swap, decorate or extend any layer without touching the others.


🔧 Core Concepts

Now that you understand the layered architecture, let's dive into the key concepts you'll work with when building applications using the Nodeblocks Backend SDK. These concepts form the building blocks of your API and understanding them will help you create maintainable, scalable backend services.

Services

A service is a composable piece of your application that provides HTTP endpoints. It's implemented as Express middleware that you can mount on your Express application. You create a service using the defService function, which takes a composed set of features and configurations and returns an Express router ready to be used as middleware.

Composition

Composition is the central pattern in the SDK. The compose function allows you to chain together different parts of your application from left to right (unlike traditional function composition which goes right to left). You start with simple functions and progressively build them up into more complex ones, with each function being applied in the order they appear in the composition chain.

// Compose multiple features into a single service definition
const serviceDefinition = compose(feature1, feature2, feature3);

// Create the service from the composed definition
const service = defService(partial(serviceDefinition, [...]));

Primitives

Primitives are lower level helper functions that help you build blocks for your service. Two of the most commonly used primitives you are withSchema and withRoute.

withSchema

The withSchema primitive defines a JSON Schema for data validation. What makes it powerful is how it interacts with withRoute - when you compose withSchema, it sets up validation for the next route automatically.

// Define a reusable schema
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,
},
});

// Apply the same schema to multiple routes
const createUserFeature = compose(createUserSchema, createUserRoute);
const updateUserFeature = compose(createUserSchema, updateUserRoute);

withRoute

The withRoute primitive defines HTTP and WebSocket endpoints. It takes a configuration object that specifies the protocol, HTTP method (for HTTP routes), path, validators and a handler function.

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

Features

A feature is a logical grouping of related functionality, typically consisting of one or more routes and their associated schemas. You create a feature by composing its parts.

// Create a complete feature by composing schema and route
export const userFeature = compose(createUserSchema, createUserRoute);

⚡ Quickstart

Looking to spin up your first API quickly? Follow the step-by-step Quickstart tutorial which walks you through installation, server bootstrap and testing your first request.

Open the Quickstart tutorial →


📑 Available Documentation

How-To Guides

Step-by-step tutorials that walk you through common development tasks and advanced customization scenarios.

Components

In-depth explanations of each architectural component, including API references, usage patterns, and best practices.

Built-in Services

Ready-to-use services that provide common functionality out of the box, with full customization options.


🙌 Contributing

Found a bug or have an idea? Open an issue or PR on GitHub – contributions are welcome.