UNPKG

@travetto/rest-fastify

Version:

Fastify provider for the travetto rest module.

82 lines (68 loc) 2.42 kB
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 */ @Injectable() export class FastifyRestServer implements RestServer<FastifyInstance> { listening = false; raw: FastifyInstance; @Inject() 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) }; } }