Express JS调用2个get方法

时间:2018-02-21 09:53:12

标签: node.js api typescript express

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

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

我的问题如下:

我有一个名为Offers的端点,On我正在做一些像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

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

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函数被执行时,id by id函数也在执行..

编辑1:

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

知道为什么会这样吗?

请帮我解决问题。

提前致谢。

1 个答案:

答案 0 :(得分:2)

由于你有两条相互冲突的路线,所以会发生这种情况。您已获得/findByStatus/:id,两者都被触发,因为它们在技术上与端点匹配。

当您使用/:id时,您正在说&#34;选择带有/之后的任何内容,然后将该值作为req.params.id&#34;。< / p>

我的建议是删除/findByStatus并将其作为/,原因有几个。

  1. 它可以防止冲突。
  2. 这将是更多&#34; RESTful&#34;,REST系统是围绕CRUD构建的,它是一个标准,您可以用它来帮助以每个人都能理解的方式构建CRUD系统。
  3. 端点将变得更具可扩展性。
  4. 由于您的/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 可选参数,如果提供了该参数,那么您将根据状态进行过滤,如果它是&#39;没有提供,那么你可以做其他事情或只返回完整的数据集。

    这不仅可以解决您的冲突路由问题,而且还可以使您的应用程序更加RESTful,并使您能够针对单条路径扩展过滤器选项。