Alepha Server
Core HTTP server for creating REST APIs.
Installation
This package is part of the Alepha framework and can be installed via the all-in-one package:
npm install alepha
Module
Provides high-performance HTTP server capabilities with declarative routing and action descriptors.
The server module enables building REST APIs and web applications using $route
and $action
descriptors
on class properties. It provides automatic request/response handling, schema validation, middleware support,
and seamless integration with other Alepha modules for a complete backend solution.
This module can be imported and used as follows:
import { Alepha, run } from "alepha";
import { AlephaServer } from "alepha/server";
const alepha = Alepha.create()
.with(AlephaServer);
run(alepha);
API Reference
Descriptors
Descriptors are functions that define and configure various aspects of your application. They follow the convention of starting with $
and return configured descriptor instances.
For more details, see the Descriptors documentation.
$action()
Creates a server action descriptor for defining type-safe HTTP endpoints.
Server actions are the core building blocks for REST APIs in the Alepha framework. They provide a declarative way to define HTTP endpoints with full TypeScript type safety, automatic schema validation, and integrated security features. Actions automatically handle routing, request parsing, response serialization, and OpenAPI documentation generation.
Key Features
- Type Safety: Full TypeScript inference for request/response types
- Schema Validation: Automatic validation using TypeBox schemas
- Auto-routing: Convention-based URL generation with customizable paths
- Multiple Invocation: Call directly (
run()
) or via HTTP (fetch()
) - OpenAPI Integration: Automatic documentation generation
- Security Integration: Built-in authentication and authorization support
- Content Type Detection: Automatic handling of JSON, form-data, and plain text
URL Generation
By default, actions are prefixed with /api
(configurable via SERVER_API_PREFIX
):
- Property name becomes the endpoint path
- Path parameters are automatically detected from schema
- HTTP method defaults to GET, or POST if body schema is provided
Use Cases
Perfect for building robust REST APIs:
- CRUD operations with full type safety
- File upload and download endpoints
- Real-time data processing APIs
- Integration with external services
- Microservice communication
- Admin and management interfaces
Basic CRUD operations:
import { $action } from "alepha/server";
import { t } from "alepha";
class UserController {
getUsers = $action({
path: "/users",
description: "Retrieve all users with pagination",
schema: {
query: t.object({
page: t.optional(t.number({ default: 1 })),
limit: t.optional(t.number({ default: 10, maximum: 100 })),
search: t.optional(t.string())
}),
response: t.object({
users: t.array(t.object({
id: t.string(),
name: t.string(),
email: t.string(),
createdAt: t.datetime()
})),
total: t.number(),
hasMore: t.boolean()
})
},
handler: async ({ query }) => {
const { page, limit, search } = query;
const users = await this.userService.findUsers({ page, limit, search });
return {
users: users.items,
total: users.total,
hasMore: (page * limit) < users.total
};
}
});
createUser = $action({
method: "POST",
path: "/users",
description: "Create a new user account",
schema: {
body: t.object({
name: t.string({ minLength: 2, maxLength: 100 }),
email: t.string({ format: "email" }),
password: t.string({ minLength: 8 }),
role: t.optional(t.enum(["user", "admin"]))
}),
response: t.object({
id: t.string(),
name: t.string(),
email: t.string(),
role: t.string(),
createdAt: t.datetime()
})
},
handler: async ({ body }) => {
// Password validation and hashing
await this.authService.validatePassword(body.password);
const hashedPassword = await this.authService.hashPassword(body.password);
// Create user with default role
const user = await this.userService.create({
...body,
password: hashedPassword,
role: body.role || "user"
});
// Return user without password
const { password, ...publicUser } = user;
return publicUser;
}
});
getUser = $action({
path: "/users/:id",
description: "Retrieve user by ID",
schema: {
params: t.object({
id: t.string()
}),
response: t.object({
id: t.string(),
name: t.string(),
email: t.string(),
role: t.string(),
profile: t.optional(t.object({
bio: t.string(),
avatar: t.string({ format: "uri" }),
location: t.string()
}))
})
},
handler: async ({ params }) => {
const user = await this.userService.findById(params.id);
if (!user) {
throw new Error(`User not found: ${params.id}`);
}
return user;
}
});
updateUser = $action({
method: "PUT",
path: "/users/:id",
description: "Update user information",
schema: {
params: t.object({ id: t.string() }),
body: t.object({
name: t.optional(t.string({ minLength: 2 })),
email: t.optional(t.string({ format: "email" })),
profile: t.optional(t.object({
bio: t.optional(t.string()),
avatar: t.optional(t.string({ format: "uri" })),
location: t.optional(t.string())
}))
}),
response: t.object({
id: t.string(),
name: t.string(),
email: t.string(),
updatedAt: t.datetime()
})
},
handler: async ({ params, body }) => {
const updatedUser = await this.userService.update(params.id, body);
return updatedUser;
}
});
}
Important Notes:
- Actions are automatically registered with the HTTP server when the service is initialized
- Use
run()
for direct invocation (testing, internal calls, or remote services) - Use
fetch()
for explicit HTTP requests (client-side, external services) - Schema validation occurs automatically for all requests and responses
- Path parameters are automatically extracted from schema definitions
- Content-Type headers are automatically set based on schema types
$route()
Create a basic endpoint.
It's a low level descriptor. You probably want to use $action
instead.
Providers
Providers are classes that encapsulate specific functionality and can be injected into your application. They handle initialization, configuration, and lifecycle management.
For more details, see the Providers documentation.
ServerNotReadyProvider
On every request, this provider checks if the server is ready.
If the server is not ready, it responds with a 503 status code and a message indicating that the server is not ready yet.
The response also includes a Retry-After
header indicating that the client should retry after 5 seconds.
ServerRouterProvider
Main router for all routes on the server side.
- $route => generic route
- $action => action route (for API calls)
- $page => React route (for SSR)
Table of contents