@glandjs/fastify@1.1.0-beta
@glandjs/fastify
The Fastify 5 transport.
# pnpm pnpm add @glandjs/fastify# npm npm install @glandjs/fastify# yarn yarn add @glandjs/fastify# bun bun add @glandjs/fastify| Package | @glandjs/fastify |
| Version | 1.1.0-beta |
| Repository | glandjs/http |
| License | MIT |
| Node | >= 20 |
| Dependencies | @glandjs/core ^1.0.3-beta · @glandjs/events ^1.1.0 · @medishn/toolkit ^1.0.4 · fastify ^5.2.1 · tslib ^2.8.1 |
| Peer dependencies | @glandjs/common ^1.0.3-beta · reflect-metadata ^0.2.2 |
Description
Section titled “Description”@glandjs/fastify is the Fastify adapter for Gland’s HTTP layer. It contributes
a Fastify instance, a FastifyContext, and nothing else — the onion, the request
lifecycle, the reply coercion and the error rendering all come from
@glandjs/http.
Fastify is the one framework here whose lifecycle is genuinely asynchronous:
listen() returns a promise because plugins are still registering, and close()
drains connections rather than dropping them.
Install
Section titled “Install”Optional, for the features that need them: @fastify/cookie, @fastify/formbody,
@fastify/static.
import { GlandFactory } from '@glandjs/core';import { FastifyBroker, type FastifyContext } from '@glandjs/fastify';import { Get } from '@glandjs/http';import { Controller, Module } from '@glandjs/common';
@Controller('/products')class ProductController { @Get('/:id') async find(ctx: FastifyContext) { return ctx.call('db:product:find', ctx.params.id); }}
@Module({ controllers: [ProductController] })class AppModule {}
const { app, shutdown } = await GlandFactory.create(AppModule);const http = app.connectTo(FastifyBroker, { poweredBy: false });
http.listen(3000);await http.ready(); // Fastify loads plugins asynchronouslyhttp.fastify.register(require('@fastify/helmet'));The middleware onion is real here
Section titled “The middleware onion is real here”Fastify has no use(), and its hook chain is a hand-off — a hook continues it by
returning. Mounting one hook per Gland middleware would therefore give N
independent middlewares rather than an onion: outer would finish before inner
began.
So the adapter mounts one preHandler hook and walks the Gland chain inside
it as a promise-based onion:
app.use(async (ctx, next) => { const started = Date.now(); await next(); // the downstream half has finished metrics.timing('route', Date.now() - started);});What is given up is the ability for a Gland middleware to short-circuit into a
Fastify hook, which is rare and reachable through app.fastify if you need it.
WebDAV
Section titled “WebDAV”Fastify 5 routes only its own default method set, and addHttpMethod() refuses
anything outside node:http#METHODS. So:
PROPFIND, SEARCH, COPY, MOVE, LOCK, … |
work — declared with addHttpMethod |
MKWORKSPACE, UPDATE |
no equivalent — the adapter warns at boot |
[HTTP:Fastify] WARN Fastify cannot route "MKWORKSPACE" (Provided method is invalid!). The method is not in node:http#METHODS, so it has no Fastify equivalent. Use @glandjs/express, @glandjs/koa, @glandjs/hono or @glandjs/node if the application needs it.Reported at boot rather than at request time, because a route that cannot be
registered is a configuration problem and a 500 in production is not.
useRaw has no meaning
Section titled “useRaw has no meaning”Fastify has no use(). A framework-native middleware is a plugin:
app.fastify.register(require('@fastify/helmet'));app.fastify.register(require('@fastify/rate-limit'), { max: 100 });app.useRaw(...) is reported and ignored, because a silently-dropped
compression() leaves an application that believes it is compressed.
Logging
Section titled “Logging”Fastify’s own logger is off by default. Gland publishes the lifecycle events, and
two loggers emitting the same line per request is worse than one. Turn Fastify’s
back on through app.fastify if you want it.
| Export | Kind |
|---|---|
FastifyBroker / FastifyBrokerClass |
What app.connectTo() takes |
FastifyCore |
The application, with a typed fastify getter |
FastifyAdapter |
The adapter |
FastifyContext, FastifyRouteOptions |
The context |
The full surface is in the API reference.
Documentation
Section titled “Documentation”License
Section titled “License”MIT