打字稿,Express Rest API 路由未加载

Typescript, Express Rest API routes not loading

我正在尝试访问我创建的其余 API 的数据,但是路由没有显示任何 JSON 数据。我有服务器、控制器和数据控制器 类,用于初始化和配置 API。服务器与两个控制器一起正确加载,但当我转到端点时,它只显示默认的 React 应用程序页面。

服务器负载控制器方法:

public loadControllers(controllers: Array<Controller>): void {
        controllers.forEach(controller => {
            console.log(controller, controller.path)
            this.app.use(controller.path, controller.setRoutes());
        });
    };

控制器设置路由方法:

public setRoutes = (): Router => {
        for (const route of this.routes) {
            for (const mw of route.localMiddleware) {
                this.router.use(route.path, mw)
            };
            switch (route.method) {
                case Methods.GET:
                    this.router.get(route.path, route.handler);
                    break;
                case Methods.POST:
                    this.router.post(route.path, route.handler);
                    break;
                case Methods.PUT:
                    this.router.put(route.path, route.handler);
                    break;
                case Methods.DELETE:
                    this.router.delete(route.path, route.handler);
                    break;
                default:
                    console.log('not a valid method')
                    break;
            };
        };
        
        return this.router;
    }

DataController 示例路由和处理程序:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations,
            localMiddleware: [],
        },
]

async handleGetLocations (req: Request, res: Response, next: NextFunction, id?: number) {
        try{
            this.dbConn.initConnectionPool()
                .then((pool) => {
                    pool.query(`query here`)
                })
                .then((data) => {
                    res.send(data);
                })
        }
        catch(err){
            console.log(err);
        }
    }

当我控制台记录路由或任何功能时,它们都正确显示。

首先,您在 this 处理方面遇到了问题。当你做这样的事情时:

this.router.get(route.path, route.handler);

router.handler 指向一个函数,例如你的 handleGetLocations(),它期望使用 this 并期望它是你的对象,this 的值不会'没有正确的值。您要么需要 .bind() this 到您的函数,要么您需要正确使用 arrow 函数来保留 this.

的正确值

this 的值错误时, handleGetLocations()function will fail becausethis` 中的 this.dbConn.initConnectionPool() 之类的值不正确。

您在问题的代码中没有显示足够的整体上下文,因此我们无法理解 this 应该指向什么以及因此如何正确声明或构造事物来解决问题。

有可能,您可以更改此代码:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations,
            localMiddleware: [],
        },
]

对此:

routes = [
        {
            path: '/locations',
            method: Methods.GET,
            handler: this.handleGetLocations.bind(this),
            localMiddleware: [],
        },
]

但是,只有当 this 在我们没有足够的代码上下文来真正知道的数组声明中具有正确的值时,这才会起作用。 您的代码中还有其他问题,例如 handleGetLocations() 中没有正确的错误处理。如果 this.dbConn.initConnectionPool() 拒绝,则您没有处理程序。您要么需要 await 它以便您的 try/catch 会收到拒绝,要么您需要 .catch().then() 之后收到拒绝。


仅供参考,在另一个框架之上添加您自己的框架在这​​里似乎不必要地复杂。你已经用你自己的系统掩盖了 Express 中非常简单的路由声明,这引入了新的问题,并没有真正使任何事情变得更清楚,也是一个其他人不熟悉的系统。


哦,还有一件事。此代码:

async handleGetLocations(req: Request, res: Response, next: NextFunction, id ? : number) {
    try {
        await this.dbConn.initConnectionPool()
            .then((pool) => {
                pool.query(`query here`)
            })
            .then((data) => {
                res.send(data);
            })
    } catch (err) {
        console.log(err);
    }
}

需要解决几件事。如上所述,您必须修复 this 传递给此函数的方式。然后,您必须修复错误处理以实际从此处的任一异步调用中捕获被拒绝的承诺。然后,您必须实际捕获 pool.query() 的结果,以便您可以对其进行处理。你忽略了它。 然后,如果承诺被拒绝,您必须实际发送错误响应。

async handleGetLocations(req: Request, res: Response, next: NextFunction, id ? : number) {
    try {
        const pool = await this.dbConn.initConnectionPool();
        const data = await pool.query(`query here`);
        res.send(data);
    } catch (err) {
        console.log(err);
        res.sendStatus(500);
    }
}

你的框架是不是在一个框架之上还有其他问题,我们用这么多的代码是无法判断的。单步执行一个包含一个 GET 路由的简单测试应用程序应该能够确定您是否最终配置了正确的 Express 路由,以及该路由处理程序是否被调用过。由于我们这里没有可重现、可运行的代码集,因此我们无能为力。正如我上面所说的,我不喜欢将您自己的框架放在现有框架之上,因为它看起来只是增加了一个复杂性级别而没有显着的好处。而且,您现在也必须正确调试(因为它还不能工作)并维护您的框架。