基于 typescript 装饰器实现 express 路由
import 'reflect-metadata';
import express, { Request, Response, NextFunction } from 'express';
const METADATA_KEY = Symbol('route_metadata');
interface RouteMetadata {
path: string;
requestMethod: 'get' | 'post';
}
function route(metadata: RouteMetadata) {
return function (target: any, propertyKey: string) {
Reflect.defineMetadata(METADATA_KEY, metadata, target, propertyKey);
};
}
function isController(target: any) {
return !!target.isController;
}
function registerRoutes(app: express.Application, controller: any) {
const proto = controller.prototype;
for (const key in proto) {
if (isRoute(proto, key)) {
const metadata: RouteMetadata = Reflect.getMetadata(METADATA_KEY, proto, key);
const handler = proto[key].bind(proto);
app[metadata.requestMethod](metadata.path, handler);
}
}
}
function isRoute(target: any, propertyKey: string) {
return !!Reflect.getMetadata(METADATA_KEY, target, propertyKey);
}
@route({ path: '/example', requestMethod: 'get' })
class ExampleController {
isController = true;
@route({ path: '/example', requestMethod: 'get' })
getExample(req: Request, res: Response, next: NextFunction) {
res.send('Hello, World!');
}
}
const app = express();
registerRoutes(app, ExampleController);
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
这段代码定义了一个名为route
的装饰器,用于标注Express路由的元数据。然后定义了一个控制器类ExampleController
,其中包含一个标注有route
装饰器的方法getExample
。最后,在express
应用中注册了这个控制器的路由。这个例子展示了如何使用装饰器来简化Express路由的定义,提高代码的可读性和维护性。
评论已关闭