找不到资源时,我应该返回204或404响应吗?


15

我正在为比赛和日程表开发一个简单的RESTful服务。通过包含JSON正文的POST请求创建锦标赛时,会将锦标赛插入,BiMap在DAO实现中声明如下:

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

创建锦标赛时,将返回其关联的字符串ID,以便用户将来可以参考该锦标赛。他/她可以从执行以下请求的新锦标赛中获取信息:

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

但是,如果找不到具有此类ID的锦标赛怎么办?到目前为止,我将返回204响应。好吧,泽西岛null从其中一种方法返回时正在为我做这件事。这是与上述路线相对应的方法:

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

我的问题是:可以返回204: No Content响应,还是应该返回404响应,因为找不到资源?

如果我应该将其更改为404,则会出现一个明显的问题:我应该更改方法签名吗?由于现在Tournament可能不会返回(类型为)锦标赛,因此方法应该看起来有所不同。我应该使用该Response类型作为返回类型吗?

Answers:


32

HTTP 204手段的东西发现,但它是空的。例如,假设您正在通过HTTP提供日志文件,并带有诸如http://example.com/logs/[date-goes-here]之类的请求。2015年5月18日:

如果提供null给框架作为对请求的响应,则假定您找到了一个条目,并且该条目为空,因此为HTTP 204。相反,您应该throw new NotFoundException();向框架指示该条目不存在,以便它将生成一个HTTP 404

如果我将其更改为404,则会出现一个明显的问题:我应该更改方法签名吗?

不,你没有。真是太好了throw new NotFoundException();。无论您的方法的实际返回类型是什么,它都将起作用。


5
请特别注意RFC 2616。如果您完全忽略消息正文,则204个响应仅符合规范。在某种程度上,204响应的目的是说:“不,我没有返回任何内容不是偶然的。” 以MainMa的示例为例:如果日志查找工具吐出文本文件(例如,将日志文件按原样吐出的薄薄包装纸),则204适用于空日志文件。如果响应是一个空的JSON对象(例如{content: ''}),则204响应将是不合适的。
布赖恩

因为,很难记录未来。 ”-这取决于任意日期;为什么不制作不需要读者假装不是今天的东西?也许使用2015-02-29会更好,因为这是一个根本不存在的日期?
基金莫妮卡的诉讼


1

您的要求是GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

如果http://localhost:8080/eventscheduler/不存在作为端点,则应返回404。您正在尝试访问/eventscheduler/不存在的资源()。这将向客户端表明服务器位于上localhost:8080,但是eventscheduler端点上没有任何内容。

如果http://localhost:8080/eventscheduler/作为端点存在,但是所需的资源不可用,则5xx错误是适当的。一个很好的例子是数据库是否处于脱机状态,您可以在其中返回503。当然,您可能只想返回通用500错误而不是特定实例。

如果http://localhost:8080/eventscheduler/存在但由表示的事物c15268ce-474a-49bd-a623-b0b865386f39不存在,我将返回200,并带有指示细节的正文。端点存在,发出的请求完全有效并且可以处理,但是没有匹配项。

如果客户对端点的请求无效,则将查看其他4xx错误。您可以使用401或403指示客户端无权访问端点或所请求的项目,或者可以使用400指示该请求无效。通过这些方法中的任何一个,都可以在响应主体中提供其他信息。


无需区分端点和资源。如果URI由于任何原因与任何资源都不匹配,则服务器应返回
404。– bdsl

检查此站点上的响应代码,以获取该站点执行正确操作的示例。这是一个网站,而不是API,但适用相同的http规范。softwareengineering.stackexchange.com/questions/266183385
bdsl

@bdsl我可以告诉你这是绝对错误的。例如,我正在与可以返回用户个人资料的用户服务进行交互。假设这个端点是/user和一样使用/user?email=test@example.com。作为一个API使用者,我想知道/user服务器上是否不存在某种原因(也许是因为它是在API的v2中添加的,并且服务器是在v1上还是在v3中已被重命名),或者用户是否收到了电子邮件test@example.com不存在。第一个是404,第二个是200,其主体表示没有使用该电子邮件地址的用户。
Thomas Owens

@bdsl很好,但这并不意味着它正确或最佳。我也不认为您可以将设计用于通过Web浏览器进行人机交互的网站与设计用于软件系统的API进行比较。
Thomas Owens

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.