例如,您运行GET请求users/9但没有id为#9的用户.哪个是最好的响应代码?
我今天与同事讨论过使用REST URL中的查询字符串.拿这两个例子:
1. http://localhost/findbyproductcode/4xxheua
2. http://localhost/findbyproductcode?productcode=4xxheua
Run Code Online (Sandbox Code Playgroud)
我的立场是应该按照示例1设计URL.这更清晰,我认为在REST中是正确的.在我看来,如果产品代码不存在则从示例1返回404错误是完全正确的,而示例2返回404将是错误的,因为页面应该存在.他的立场是,它并不重要,他们都做同样的事情.
由于我们都没有找到具体的证据(诚然,我的搜索并不广泛),我想知道其他人对此的看法.
我正在构建一个RESTful Web服务.我已经阅读了为每个机制使用HTTP的原则,只要它会占用你,而且大多数时候,就像获取资源一样,它工作得很好.
但是当我需要发布某种新条目时,为了清晰和健壮,无论客户端做什么,我都想提供新条目可能失败的特定验证错误.此外,存在特定错误,例如,用于创建新用户的数据完全有效,但可以采用昵称或电子邮件地址.简单地返回409 Conflict没有详细说明昵称或电子邮件地址的详细信息.
所以解决这个问题不是火箭科学:记录一堆特定的错误代码并返回一个有错误的对象:
{ errors: [4, 8, 42] }
Run Code Online (Sandbox Code Playgroud)
这意味着在请求失败的情况下,我不会返回REST哲学所预期的资源或密钥.类似地,当我返回许多资源时,我必须以某种方式在数组中构造它们.
所以我的问题是:如果我为每个请求标准化一个信封,我是否仍然会提供一个表现良好的RESTful Web服务,例如,总有一个像这样的对象{ errors, isSuccessful, content }?
我之前已经构建了使用它的RPC风格的Web服务,但我不想做一些"几乎是REST"的东西.如果有任何关于REST的意义,我希望尽可能保持良好的行为.
如果答案是"地狱没有",我认为它可能是,我想知道它是否至少正确地解决了验证问题,并且对于这种问题解决可能是一个很好的参考,因为大多数指南我都是我发现只详细的简单案例.
我正在使用NestJS开发后端(这真是太棒了).我有一个'标准获取实体情况的单一实例',类似于下面这个例子.
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
..
..
..
@Get(':id')
async findOneById(@Param() params): Promise<User> {
return userService.findOneById(params.id);
}
Run Code Online (Sandbox Code Playgroud)
这非常简单且有效 - 但是,如果用户不存在,则服务返回undefined,并且控制器返回200状态代码和空响应.
为了让控制器返回404,我想出了以下内容:
@Get(':id')
async findOneById(@Res() res, @Param() params): Promise<User> {
const user: User = await this.userService.findOneById(params.id);
if (user === undefined) {
res.status(HttpStatus.NOT_FOUND).send();
}
else {
res.status(HttpStatus.OK).json(user).send();
}
}
..
..
Run Code Online (Sandbox Code Playgroud)
这是有效的,但代码更多(是的,它可以重构).
这可能真的使用装饰器来处理这种情况:
@Get(':id')
@OnUndefined(404)
async findOneById(@Param() params): Promise<User> {
return userService.findOneById(params.id);
}
Run Code Online (Sandbox Code Playgroud)
任何人都知道这样做的装饰者,或者比上面的解决方案更好的解决方案?