Add BunHttpServer and HttpServerFactory classes for handling HTTP requests

* Implemented BunHttpServer to manage routes and WebSocket handling
* Created HttpServerFactory for instantiating BunHttpServer with routes and WebSocket handlers
* Added error handling for duplicate routes and a default fetch response for unknown routes
This commit is contained in:
2025-11-21 03:04:10 -05:00
parent f66266b218
commit 4f0348ec1a
2 changed files with 61 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
import {LoggerFactory} from '@techniker-me/logger';
import type {Server as BunServer, BunRequest, WebSocketHandler} from 'bun';
export type BunRouteHandler = (request: BunRequest, server: BunServer<unknown>) => Promise<Response>;
export type BunMethodRoutes = {
GET: BunRouteHandler;
POST: BunRouteHandler;
PUT: BunRouteHandler;
DELETE: BunRouteHandler;
PATCH: BunRouteHandler;
OPTIONS: BunRouteHandler;
};
export type BunRoutes = Record<string, BunMethodRoutes | BunRouteHandler>;
export class BunHttpServer<T> {
private readonly _logger = LoggerFactory.getLogger('BunHttpServer');
private readonly _webSocketHandler: WebSocketHandler<T> | undefined;
private readonly _routes: BunRoutes;
constructor(routes: BunRoutes, webSocketHandler: WebSocketHandler<T> | undefined) {
this._routes = routes;
this._webSocketHandler = webSocketHandler;
this.fetch = this.fetch.bind(this);
}
get websocket(): WebSocketHandler<T> | undefined {
return this._webSocketHandler;
}
get routes(): BunRoutes {
return this._routes;
}
public addRoute(path: string, handler: BunRouteHandler): void {
if (this._routes[path]) {
throw new Error(`Route [${path}] already exists`);
}
this._routes[path] = handler.bind(this);
}
public async fetch(request: BunRequest, server: BunServer<unknown>): Promise<Response> {
const url = new globalThis.URL(request.url);
this._logger.info('Received [%s] request from [%s] for unknown route [%s]', request.method, server.requestIP(request)?.address ?? 'unknown', url.pathname);
return new Response(JSON.stringify({status: 'not-found'}), {status: 404, headers: {'Content-Type': 'application/json'}});
}
}

View File

@@ -0,0 +1,12 @@
import {BunHttpServer, type BunRoutes} from './BunHttpServer';
import type {WebSocketHandler} from 'bun';
export default class HttpServerFactory {
public static createBunHttpServer(routes: BunRoutes, webSocketHandler: WebSocketHandler<unknown> | undefined): BunHttpServer<unknown> {
return new BunHttpServer(routes, webSocketHandler);
}
private constructor() {
throw new Error('This class is a static class that may not be instantiated');
}
}