我不同意迈克尔的答案,并以此作为我自己答案的基础:
“将你的 Web url 与 API URL 分离,以便它们每个 URL 都可以独立地更改”,就是在面对 REST 时吐口水。很酷的 URI 不会改变。不要担心更改网址。不要使用 URI 对 API 进行版本控制。REST 使用链接来支持 OCP - 在以前版本的 API 上运行的客户端应该很乐意关注上线时存在的链接,而不知道您为增强 API 而添加的新链接。
如果您坚持对 API 进行版本控制,我会要求您使用媒体类型而不是 URI。
接下来,“你简化了你的实现。现在,每个方法都不必确定它是在 JSON/XML 还是 HTML 前面。
如果你这样做,你做错了。来自泽西岛,我从每个方法返回相同的该死的对象,无论我是否生成HTML,XML或JSON。这是一个完全跨领域的问题,由编组人员负责。我使用 VelocityMessageBodyWriter 来发出围绕我的 REST 表示的 HTML 模板。
我的系统中的每个资源都遵循相同的基本行为:
class FooResource extends Resource {
@GET
public FooRepresentation get() {
return new FooRepresentation();
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response postForm(MulivaluedMap<String, String> form) {
return post(buildRepresentationFromForm(form));
}
@POST
@Consumes(MediaType.APPLICATION_XML)
public Resopnse post(FooRepresentation representation) {
// return ok, see other, whatever
}
}
GET 方法可能需要构建指向其他资源的链接。这些由 REST API 和 HTML 模板的使用者使用。表单可能必须POST,并且我使用某些特定的链接(由关系定义)作为“操作”属性)。
用户浏览器和用户机器之间通过系统的路径可能不同,但这不是实现的分离 - 它是REST!状态转移按照它需要的方式发生,你如何定义它。用户(在浏览器中)如何继续。
“最后,通过将站点与API分开,您可以满足不同的扩展需求。如果你的API受到重创,但网站没有受到重创,你可以在API上投入更多的硬件,同时保持网站所需的最少硬件。很有可能你在幕后做了一些比仅仅提供HTML更激烈的工作。通过使用相同的实现,扩展变得更加容易。API本身(XML和域对象之间的封送处理以及返回)不会超过业务逻辑和处理,数据库等。
最后,通过保持它们相同,可以更轻松地将系统视为一个整体。事实上,从 HTML 开始。定义关系。如果您很难在HTML锚点和表单中表达特定的操作或用户故事,那么您可能偏离了REST。
记住,你是把事物表达为(特定关系)与其他事物的链接。这些URI甚至可能有所不同,具体取决于您是生成XML还是HTML - HTML页面可能会发布到URI some / uri / a,API可能会发布到某些/ uri / b - 这是无关紧要的,并且关注实际的URI内容是POX和RPC的黑暗路径
另一个漂亮的功能是,如果你这样做,你就不依赖于JavaScript。您已经定义了您的系统以使用基本的HTML,并且可以在JavaScript可用时“翻转” JavaScript。然后你真的在使用你的“API”(我害怕将它们称为不同的东西,但我也试图将我的回应与你的措辞联系起来)
**我将添加最后一个注释,在生成HTML时,我使用303而不是201,以便于POST-then-GET。如果启用了JS,那么您实际上是在谈论XML(或JSON),并且您又回到了201。