Express JS调用2个get方法 [英] Express JS calling 2 get methods

查看:126
本文介绍了Express JS调用2个get方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我陷入了一些愚蠢的问题(对此不确定).

I am stuck some silly problem (not sure about this).

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

I am using Express with Typescript for my API creation.

我的问题如下:

我有1个称为Offer的终结点,并且我正在执行诸如findBy Status之类的一些操作以及CRUD操作,我的控制器如下:

I have 1 endpoint called Offers, and On that I am doing some operations like findBy Status etc along with CRUD operations, my controller is as follows:

@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

So now when I call findByStatus with POSTMAN

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

然后它也为我提供了适当的响应,但随后又再次调用了我的ID方法,因此它向我显示了以下错误:

then it providing me proper response as well but then it again calling my get by ID method as well, so it showing me errors as follows:

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功能也正在执行..

I have checked with adding console logs and it showing me that when my Find My status function gets executed then get by id function is also executing..

我正在使用快速打字稿模板 用于基本设置和路由.

I am using Express Typescript Boilerplate for basic setup and for routing.

知道为什么会发生吗?

请帮助我解决此问题.

先谢谢了.

推荐答案

这是由于您的路由而发生的,因为您有两条相互冲突的路由.您已经/findByStatus/:id都被触发了,因为它们在技术上都与端点匹配.

This is going to happen due to your routing as you've got two conflicting routes. You've got /findByStatus and /:id, both are being triggered because they both technically match the endpoint.

使用/:id时,您说的是:用它后面的东西捡起去/的任何东西,然后给我这个值req.params.id".

When using /:id you are saying "pick up anything that goes to the / with something after it, then give me that value as req.params.id".

出于某些原因,我的建议是删除/findByStatus并使其与/一样.

My advice would be to drop the /findByStatus and have it just as / for several reasons.

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

由于/findByStatus基本上只是将过滤器应用于索引路由的一种类型,因此您应该可以执行类似的操作.

Since your /findByStatus is basically just a type if filter applied to your indexing route you should be able to do something like this.

@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设置为可选参数,如果提供了该参数,则将按状态进行过滤;如果未提供,则可以执行其他操作或只需返回完整的数据集即可.

In this scenario, you're now making status an optional parameter, if it is supplied then you'll filter by the status, if it's not supplied then you could do something else or just return the full dataset.

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

Not only will this stop your conflicting route issue, but you'll also make your application more RESTful and enable you to extend your filter options against a single route.

这篇关于Express JS调用2个get方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆