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:
49
src/net/http/BunHttpServer.ts
Normal file
49
src/net/http/BunHttpServer.ts
Normal 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'}});
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/net/http/HttpServerFactory.ts
Normal file
12
src/net/http/HttpServerFactory.ts
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user