我正在创建一个基于Express Router的路由器,它的功能类似于Laravel的路由器。
我希望能够编写这样的代码:
Route.group("/api", () => {
Route.get("/auth/login", myLoginFunction)
Route.get("/auth/register", myRegisterFunction)
})但是我如何找出这些路由是在哪个组下调用的呢?我的Route类如下所示:
export class Route {
#routes: Array<IRoute>;
public static group(name: string, cb: Function) {
}
public static get(name: string, cb: Function) {
}
}我想我应该在每条路由前加上组名,但我不知道如何在每条子路由中访问组名。有什么建议吗?
发布于 2021-07-20 14:55:45
您可以在调用群组回调之前定义静态变量来配置群组,如prefix。
对模板的次要更改包括:
#routes静态,否则如果不实例化没有public关键字,则无法访问它。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Route {
static #prefix='';
static #routes = [];
// if using express.Router in backend.
// static #expressRouter = express.Router();
// prepare config variables for group
static #prepareGroup(name: string = '') {
Route.#prefix=name;
Route.#prefix += name.endsWith('/') ? '' : '/';
}
static group(name: string, cb: Function) {
Route.#prepareGroup(name);
cb();
Route.#prepareGroup();
}
static get(name: string, cb: Function) {
Route.#routes.push({
path: `${Route.#prefix}name`,
method: 'GET',
cb
});
// or if using `expressRouter`, use instead
// expressRouter.get(name, cb);
}
static _showRoutes() {
console.log(Route.#routes);
}
}
// dummy functions
const myLoginFunction = () => {}
const myRegisterFunction = () => {}
Route.group("/api", () => {
Route.get("/auth/login", myLoginFunction)
Route.get("/auth/register", myRegisterFunction)
})
Route._showRoutes()
</script>
发布于 2021-07-20 20:44:49
在研究了AdonisJS如何实现路由器后,我发现了一个通用的解决方案。下面是我的最后一段代码供参考,它的用法如下:
import {Router} from "fastia/kernel/RouteServiceProvider";
Router.group("api", () => {
Router.group("auth", () => {
Router.get("login", (_, res) => {
return res.send({
message: "hello"
})
}).middleware(["has:testquery", "admin"])
Router.get("register", () => null).middleware(["has:funquery"])
Router.group("password", () => {
Router.get("forgot", () => null)
Router.get("reset", () => null)
})
})
Router.get("test", () => null)
})路由器代码:
import {Router as ExpressRouter} from "express";
import {IMiddlewareCollection} from "../middleware/IMiddleware";
export class RouteGroup {
public routes: (Route | RouteGroup)[] = [];
public name;
constructor(name: string) {
this.name = name;
}
public populate(route: (Route | RouteGroup), params: string) {
if (route instanceof RouteGroup) {
route.routes.forEach(child => this.populate(child, params));
return;
}
route.prefix(params);
}
}
export class Route {
public prefixes: string[] = [];
public path: string;
public method: string;
public handler: Function;
public middlewares?: Array<string>;
constructor(path: string, method: string, handler: Function, middlewares?: Array<string>) {
this.path = path;
this.method = method;
this.handler = handler;
this.middlewares = middlewares;
this.prefixes.push(this.path)
}
public prefix(path: string) {
this.prefixes.unshift(path);
}
public getPath() {
return "/" + this.prefixes.join("/")
}
public middleware(middlewares: Array<string>) {
this.middlewares = middlewares;
}
}
export class Router {
public routes: (Route | RouteGroup)[] = [];
public openedGroups: Array<RouteGroup> = [];
private router: ExpressRouter = ExpressRouter();
private middlewareCollection: IMiddlewareCollection;
public static instance: Router;
public setMiddlewares(middlewareCollection: IMiddlewareCollection) {
this.middlewareCollection = middlewareCollection;
}
private getRecentGroup() {
return this.openedGroups[this.openedGroups.length - 1];
}
private route(path: string, method: string, handler: Function) {
const route = new Route(path, method, handler);
const openedGroup = this.getRecentGroup();
if (openedGroup) {
openedGroup.routes.push(route)
} else {
this.routes.push(route)
}
return route;
}
public _get(path: string, handler: Function) {
return this.route(path, "get", handler);
}
public _group(name: string, cb: Function) {
const group = new RouteGroup(name);
const openedGroup = this.getRecentGroup();
if (openedGroup) {
openedGroup.routes.push(group)
} else {
this.routes.push(group);
}
this.openedGroups.push(group);
cb();
this.openedGroups.pop();
group.populate(group, group.name);
}
public static group(name: string, cb: Function) {
return this.getInstance()._group(name, cb);
}
public static get(path: string, handler: Function) {
return this.getInstance()._get(path, handler);
}
private parseRoute(route: (Route | RouteGroup)) {
if (route instanceof RouteGroup) {
route.routes.forEach(child => this.parseRoute(child))
} else {
console.log(route.getPath());
if (route.middlewares?.length) {
const middlewares: Function[] = [];
route.middlewares.forEach(x => {
if (this.middlewareCollection[x]) {
middlewares.push(this.middlewareCollection[x].handle);
}
})
this.router[route.method](route.getPath(), ...middlewares, route.handler);
} else {
this.router[route.method](route.getPath(), route.handler);
}
}
}
public run() {
this.routes.forEach(route => this.parseRoute(route));
}
public getRouter() {
return this.router
}
public static create() {
this.instance = new this();
return this.instance
}
public static getInstance() {
return this.instance
}
}https://stackoverflow.com/questions/68447684
复制相似问题