Node.js expressjs调用2个get方法

Node.js expressjs调用2个get方法,node.js,api,typescript,express,Node.js,Api,Typescript,Express,我遇到了一些愚蠢的问题(对此不确定) 我正在使用带有Typescript的Express创建API 我的问题如下: @Get('/findByStatus') public findByStatus(@QueryParam('status') status: string): Promise<any> { try { if (OfferValidator.validateStatus(status)) { // get data fro

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

我正在使用带有Typescript的Express创建API

我的问题如下:

@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());
    }
}
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
我有一个端点名为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());
    }
}
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

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

@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());
    }
}
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:

我使用的基本设置和路由

知道为什么会这样吗

请帮我解决这个问题


提前谢谢

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

当使用
/:id
时,您说的是“拾取任何进入
/
的东西,然后将该值作为req.params.id提供给我”

我的建议是删除
/findByStatus
,并将其与
/
一样,原因如下

  • 这将防止冲突
  • 这将更加“RESTful”,REST系统是围绕CRUD构建的,这是一个标准,您可以使用它以每个人都能理解的方式帮助构建CRUD系统
  • 端点将变得更加可扩展
  • 由于
    /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);
            }
        }
    }
    
    @Get('/'))
    公共索引(@QueryParam('status')status?:字符串):承诺{
    如果(状态){
    试一试{
    if(OfferValidator.validateStatus(状态)){
    //从服务获取数据
    const data=this.offerService.findStatus(状态);
    如果(数据){
    返回此.offerService.findStatus(状态);
    }否则{
    退货承诺。拒绝(新报价有效性错误(404,‘未找到报价ID’);
    }
    }否则{
    退货承诺。拒绝(新报价有效性错误(404,‘未找到报价ID’);
    }
    }捕获(错误){
    返回承诺。拒绝(错误);
    }
    }
    }
    
    在这个场景中,您现在将
    status
    设置为一个可选的参数,如果提供了该参数,那么您将根据状态进行过滤,如果未提供该参数,那么您可以执行其他操作,或者只返回完整的数据集


    这不仅可以阻止冲突路由问题,还可以使应用程序更加RESTful,使您能够针对单个路由扩展筛选选项。

    这是由于您有两个冲突路由而导致的。您有
    /findByStatus
    /:id
    ,这两个都被触发,因为它们在技术上都与端点匹配

    当使用
    /:id
    时,您说的是“拾取任何进入
    /
    的东西,然后将该值作为req.params.id提供给我”

    我的建议是删除
    /findByStatus
    ,并将其与
    /
    一样,原因如下

  • 这将防止冲突
  • 这将更加“RESTful”,REST系统是围绕CRUD构建的,这是一个标准,您可以使用它以每个人都能理解的方式帮助构建CRUD系统
  • 端点将变得更加可扩展
  • 由于
    /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);
            }
        }
    }
    
    @Get('/'))
    公共索引(@QueryParam('status')status?:字符串):承诺{
    如果(状态){
    试一试{
    if(OfferValidator.validateStatus(状态)){
    //从服务获取数据
    const data=this.offerService.findStatus(状态);
    如果(数据){
    返回此.offerService.findStatus(状态);
    }否则{
    退货承诺。拒绝(新报价有效性错误(404,‘未找到报价ID’);
    }
    }否则{
    退货承诺。拒绝(新报价有效性错误(404,‘未找到报价ID’);
    }
    }捕获(错误){
    返回承诺。拒绝(错误);
    }
    }
    }
    
    在这个场景中,您现在将
    status
    设置为一个可选的参数,如果提供了该参数,那么您将根据状态进行过滤,如果未提供该参数,那么您可以执行其他操作,或者只返回完整的数据集


    这不仅可以解决路由冲突问题,还可以使应用程序更加RESTful,使您能够针对单个路由扩展筛选选项。

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