【问题标题】:Express JS calling 2 get methodsExpress JS调用2个get方法
【发布时间】:2018-07-31 20:26:50
【问题描述】:

我遇到了一些愚蠢的问题(不确定)。

我正在使用 Express 和 Typescript 来创建 API。

我的问题如下:

我有 1 个名为 Offers 的端点,并且我正在执行一些操作,例如 findBy Status 等以及 CRUD 操作,我的控制器如下:

@Get('/findByStatus')
public findByStatus(@QueryParam('status') status: string): Promise<any> {
    try {
        if (OfferValidator.validateStatus(status)) {
            // get data from service
            const data =  this.offerService.findStatus(status);
            if (data) {
                return this.offerService.findStatus(status);
            } else {
                return Promise.reject(new OfferInvalidError(404, 'Offer ID not found'));
            }
        } else {
            return Promise.reject(new OfferInvalidError(404, 'Offer ID not found'));
        }
    } catch (error) {
        return Promise.reject(error);
    }
}

@Get('/:id')
@OnUndefined(OfferNotFoundError)
public async one( @Param('id') id: string): Promise<Offer | undefined> {
    console.log('called id as well');
    try {
        if (OfferValidator.lengthValidator(id)) {
            return Promise.reject(new OfferInvalidError(400, 'Invalid ID supplied'));
        } else {
            console.log('coming in validator again');
            const data = await this.offerService.findOne(id);
            console.log('returned', data);
            if (!data) {
                return Promise.reject(new OfferInvalidError(404, 'Offer ID not found'));
            } else {
                data.category = JSON.parse(data.category);
                data.tags = JSON.parse(data.tags);
                return data;
            }
        }
    }  catch (e) {
        return Promise.reject(new OfferNotFoundError());
    }
}

所以现在当我用 POSTMAN 调用 findByStatus 时

http://localhost:3000/api/offer/findByStatus?status=sold

然后它也为我提供了正确的响应,但它又再次调用了我的 get by ID 方法,因此它向我显示错误如下:

called id as well
coming in validator again
info: [api:middlewares] GET /api/offer/findByStatus?status=available&status=sold 200 61.223 ms - -

returned undefined
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

我已经检查了添加控制台日志,它显示当我的 Find My status 函数被执行时,get by id 函数也在执行..

编辑 1:

我使用Express Typescript Boilerplate 进行基本设置和路由。

知道为什么会这样吗?

请帮我解决问题。

提前致谢。

【问题讨论】:

  • 请详细说明您的问题。你说“当我的 Find My status 函数被执行时,然后通过 id 函数正在执行”你是什么意思?另外,请提供工作路径和非工作路径。
  • 请用getById函数重新粘贴您的代码,也请您粘贴您的路由文件>
  • @sidgujrathi public async one() 是 getBy Id 函数
  • “然后它也为我提供了正确的响应,但它又再次调用我的 ID 获取方法”什么!?
  • @gilamran 它返回我期望从 findByStatus 函数得到的响应,但是当这个函数被执行时,它也会自动调用 get by id 方法,如果你看到错误,日志来自 get by自动执行的 id 方法

标签: node.js api typescript express


【解决方案1】:

由于您的路由有两条冲突的路由,因此会发生这种情况。你有/findByStatus/:id,它们都被触发了,因为它们在技术上都与端点匹配。

当使用/:id 时,您的意思是“拿起任何去/ 的东西,然后把它作为req.params.id 给我”。

出于多种原因,我的建议是放弃 /findByStatus 并将其保留为 /

  1. 它将防止冲突。
  2. 这会更“RESTful”,REST 系统是围绕 CRUD 构建的,它是一个标准,您可以使用它来帮助构建每个人都能理解的 CRUD 系统。
  3. 端点将变得更具可扩展性。

由于您的 /findByStatus 基本上只是一种类型,如果过滤器应用于您的索引路由,您应该能够执行类似的操作。

@Get('/')
public index(@QueryParam('status') status?: string): Promise<any> {
    if (status) {
        try {
            if (OfferValidator.validateStatus(status)) {
                // get data from service
                const data =  this.offerService.findStatus(status);
                if (data) {
                    return this.offerService.findStatus(status);
                } else {
                    return Promise.reject(new OfferInvalidError(404, 'Offer ID not found'));
                }
            } else {
                return Promise.reject(new OfferInvalidError(404, 'Offer ID not found'));
            }
        } catch (error) {
            return Promise.reject(error);
        }
    }
}

在这种情况下,您现在将 status 设置为 可选 参数,如果提供了它,那么您将按状态过滤,如果没有提供,那么您可以执行其他操作或只需返回完整的数据集。

这不仅会阻止您的路由冲突问题,而且还会使您的应用程序更加 RESTful,并使您能够针对单个路由扩展您的过滤器选项。

【讨论】:

  • @VRK 这种事情会让我发疯,很乐意提供帮助:)
  • 和我一样,我已经投入了大约 5 到 6 个小时,然后添加了关于 SO.. 的问题。再次感谢 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2021-09-27
  • 1970-01-01
  • 2016-05-26
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多