我遇到了一些愚蠢的问题(不确定)。
我正在使用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 进行基本设置和路由。
知道为什么会这样吗?
请帮我解决问题。
提前致谢。
答案 0 :(得分:2)
由于你有两条相互冲突的路线,所以会发生这种情况。您已获得/findByStatus
和/:id
,两者都被触发,因为它们在技术上与端点匹配。
当您使用/:id
时,您正在说&#34;选择带有/
之后的任何内容,然后将该值作为req.params.id&#34;。< / p>
我的建议是删除/findByStatus
并将其作为/
,原因有几个。
由于您的/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,并使您能够针对单条路径扩展过滤器选项。