跳转到内容
简体中文

Fastify backend

此内容尚不支持你的语言。

FastifyBackend is the default HTTP backend for actor-ts. Wraps Fastify — fast, well-maintained, with a huge ecosystem of plugins (JWT auth, validation, swagger, etc.).

import { ActorSystem } from 'actor-ts';
import { HttpExtensionId } from 'actor-ts/http';
const http = system.extension(HttpExtensionId);
await http.newServerAt('0.0.0.0', 8080).bind(routes);
// ↑ Fastify by default

To make the backend explicit:

import { FastifyBackend } from 'actor-ts/http';
await http.newServerAt('0.0.0.0', 8080)
.useBackend(new FastifyBackend())
.bind(routes);
new FastifyBackend({
logger: false, // Fastify's built-in logger — leave off; use actor-ts log
bodyLimit: 1_048_576, // 1 MiB request body cap
tls: {
cert: fs.readFileSync('./tls/cert.pem'),
key: fs.readFileSync('./tls/key.pem'),
},
});

Most settings pass through to Fastify’s FastifyServerOptions. The framework configures route registration; you tune Fastify’s own knobs.

bodyLimit is the one it fills in for you. Left unset it is 1 MiB — the same cap the Express and Hono backends apply, so which requests are accepted does not change with the backend. Passing your own still wins.

HttpRequest.remoteAddress comes from Fastify’s req.ip, which without trustProxy is the socket peer. Because the constructor’s options pass straight through to Fastify, trustProxy is configurable here — and if you set it, give it the addresses of your proxies:

new FastifyBackend({
trustProxy: '10.9.9.0/24', // ✓ trusted-subnet form
});

Every response this backend writes carries X-Content-Type-Options: nosniff — its error mapping, the fallback 404 and the body-too-large 413 included, none of which a middleware sees. A response’s own header still wins.

Configure it per server, not per backend — one surface instead of three:

await http.newServerAt('0.0.0.0', 8080)
.useBackend(new FastifyBackend())
.withSecurityHeaders(false) // or a SecurityHeadersOptions bundle
.bind(routes);

See Security best practices.

new FastifyBackend({
tls: {
cert: fs.readFileSync('./tls/cert.pem'),
key: fs.readFileSync('./tls/key.pem'),
// For mTLS:
ca: fs.readFileSync('./tls/ca.pem'),
requestCert: true,
rejectUnauthorized: true,
},
});

Standard Fastify TLS options. For most production setups, TLS terminates at the load balancer — the app speaks plain HTTP internally — but in-app TLS is supported when needed.

const backend = new FastifyBackend();
await http.newServerAt('0.0.0.0', 8080)
.useBackend(backend)
.bind(routes);
// After bind, register a native plugin via the escape hatch...
await backend.withPlugin(fastifyJwt, { secret: '...' });
// ...or reach the raw Fastify instance for lower-level hooks:
backend.fastify.addHook('onRequest', authHook);

Use for plugins not exposed via the framework’s DSL:

  • JWT / OAuth authentication.
  • Request validation (@fastify/swagger).
  • CORS (@fastify/cors).
  • Compression.

The actor-ts DSL handles routing; Fastify plugins handle cross-cutting concerns. They compose cleanly.

1. new FastifyBackend() — the constructor creates the Fastify instance
2. The framework registers each compiled route on Fastify
3. Fastify.listen() — opens the port
4. On shutdown: Fastify.close() — drains in-flight requests, then exits

Fastify.close() waits for in-flight requests to complete before resolving — pairs with coordinated shutdown’s service-unbind phase.

Fastify is a hard dependency of actor-ts — it installs with the framework, so there’s nothing extra to add. (The Express and Hono backends, by contrast, are optional peer dependencies you install on demand.)

Rough numbers for trivial routes:

  • 150K-200K req/sec on Bun (with bun:test benchmark).
  • 80K-120K req/sec on Node 22.
  • P50 latency sub-millisecond for trivial handlers; higher for routes that ask actors.

Fastify is one of the fastest Node HTTP frameworks; the framework’s actor-routing overhead is the next bottleneck for hot routes.