@travetto/rest-fastify
Version:
Fastify provider for the travetto rest module.
82 lines (68 loc) • 2.42 kB
text/typescript
import https from 'node:https';
import compress from '@fastify/compress';
import { FastifyInstance, fastify, FastifyHttpsOptions } from 'fastify';
import { RestConfig, RouteConfig, RestServer } from '@travetto/rest';
import { Inject, Injectable } from '@travetto/di';
import { TravettoEntitySymbol } from '@travetto/rest/src/internal/symbol';
import { ServerHandle } from '@travetto/rest/src/types';
import { FastifyServerUtil } from './internal/util';
function isHttps(ssl: boolean | undefined, cfg: https.ServerOptions): cfg is FastifyHttpsOptions<https.Server> {
return !!ssl;
}
/**
* Fastify-based rest server
*/
()
export class FastifyRestServer implements RestServer<FastifyInstance> {
listening = false;
raw: FastifyInstance;
()
config: RestConfig;
/**
* Build the fastify server
*/
async init(): Promise<FastifyInstance> {
const fastConf: https.ServerOptions = {};
if (isHttps(this.config.ssl?.active, fastConf)) {
fastConf.https = (await this.config.ssl?.getKeys())!;
}
if (this.config.trustProxy) {
Object.assign(fastConf, { trustProxy: true });
}
const app = fastify(fastConf);
app.register(compress);
app.removeAllContentTypeParsers();
app.addContentTypeParser(/^.*/, (req, body, done) => done(null, body));
this.raw = app;
return this.raw;
}
async unregisterRoutes(key: string | symbol): Promise<void> {
console.debug('Fastify does not allow for route reloading');
}
async registerRoutes(key: string | symbol, path: string, routes: RouteConfig[]): Promise<void> {
if (this.listening) { // Does not support live reload
return;
}
for (const route of routes) {
let sub = path;
if (route.path) {
sub = `${path}/${route.path}`;
}
sub = sub.replace(/\/{1,3}/g, '/').replace(/\/{1,3}$/, '');
this.raw[route.method](sub, async (req, reply) => {
await route.handlerFinalized!(
req[TravettoEntitySymbol] ??= FastifyServerUtil.getRequest(req),
reply[TravettoEntitySymbol] ??= FastifyServerUtil.getResponse(reply)
);
});
}
}
async listen(): Promise<ServerHandle> {
await this.raw.listen({ port: this.config.port, host: this.config.bindAddress });
this.listening = true;
return {
on: this.raw.server.on.bind(this.raw),
close: this.raw.close.bind(this.raw)
};
}
}