我应该在响应中返回与某项相关的网址吗

时间:2018-12-13 15:34:01

标签: rest api

在我的API中,我应该返回产品列表。在客户端(浏览器)中,用户可以将该产品添加到购物车中,以增加,减少或从购物车中删除该产品。

在我对产品列表的回复中,我应该这样进行网址操作:

{
   "alias": 'aliasValue',
   "removeUrl": 'domain/product/alias/',
   "increaseUrl": 'domain/product/alias/increase/',
   "decreaseUrl": 'domain/product/alias/decrease/',
   ...
}

这是一个好习惯,我已经搜索过了,但是我发现有关URL和API的唯一一件事就是有关URL结构。

你怎么看?

3 个答案:

答案 0 :(得分:2)

我建议不要重新发明轮子。您的API中有many ways个可以使用HATEOAS

例如,考虑使用_links属性的HAL (Hypertext Application Language)方法:

{
  "_links": {
    "self": {
      "href": "http://example.com/api/books/1"
    }
  },
  "id": "1",
  "name": "Hypermedia as First-Class Citizen"
}

答案 1 :(得分:1)

您试图实现的名称 HATEOAS 代表Hypermedia作为应用程序状态引擎。

因此,如果您进行搜索,则会发现很多格式:

  • JSON-LD
  • HAL
  • SIREN
  • ION
  • JSON API
  • 春天
  • Ripozo

来源:https://nordicapis.com/tools-to-make-hateoas-compliance-easier/

答案 2 :(得分:1)

由于REST只是众所周知的可浏览Web的泛化,因此您基本上可以应用与为浏览器实现系统相同的概念。简而言之,服务器应为客户提供所有必要的信息,客户将需要这些信息来做出有根据的决策,然后再调用哪些资源。

在基于浏览器的Web应用程序中,交互模型可能类似于调用起始页,看到响应中您感兴趣的部分,单击链接以了解更多详细信息。下一页可能会列出一些项目,为您提供了进一步的控件来修改此列表,即添加新项目,删除一个项目等等。单击某些“添加”按钮后,将向您显示一个表单,该表单可以告诉您请求应包含哪些字段,以及该请求应发送到的字段(即使您可能看不见)。在背面,浏览器将为您处理这些事情。跳跃点在于,服务器实际上是在向客户端提供完成任务所需的任何信息,无论是选择可用的链接进行探索还是提供有关请求外观的一些准则。

为了确定客户端是否对链接感兴趣,服务器将使用有意义的链接关系名称“附加”到客户端应使用的URI,而不是解析和解释URI。这允许服务器在不影响客户端的情况下随时更改URI。菲尔丁在他的一篇博客中提到了以下内容:

  

REST API应该花费几乎所有的描述性精力来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体定义扩展关系名称和/或启用超文本的标记类型。 (Source

此外,REST API对客户端不应该具有typed resources的意义,因为这基本上将客户端与API本身紧密耦合,并且如果服务对返回的响应进行了任何更改,都将导致失败。相反,应该使用内容类型协商,以便客户端和服务器就所使用的实际表示格式进行协商。

媒体类型定义为某个Content-Type HTTP标头接收的某些有效负载的处理规则。这些规则定义了文档的语法和语义。如果媒体类型中概述的规则为violated,则允许REST体系结构中的服务器拒绝针对特定内容类型发送的任何消息。

尽管专注于媒体类型并不能阻止对接收到的表示进行完全更改,但它仍然有助于帮助进一步将客户端与服务器分离,并减少与服务进行交互所需的带外信息。 。并非直接将客户端耦合到API,而是将两者都实际耦合到媒体类型,并且它们实际上可能耦合到多种媒体类型。如果需要对媒体类型进行更改,则可以轻松引入新的媒体类型,或者类似于HTML,在媒体类型内指定实现向后兼容性的方式。

关于以前的带外信息要求,REST并没有完全删除这些信息,菲尔丁说

  

客户当然有先验知识。每个协议,每个媒体类型定义,每个URI方案和每个链接关系类型都构成了客户端必须知道(或学习)的先验知识,以便利用该知识。 REST并没有消除线索的必要。 REST的工作是将对先验知识的需求集中到易于标准化的形式中。这是面向数据的集成和面向控制的集成之间的本质区别。 (Source

由于REST并非只关注一个方面,而是上述所有方面的综合,因此您的实际问题应从多个角度解决。

首先,要么使用现有的链接关系(即由IANA或其他microformats管理),定义新的链接,最好应向IANA注册,或者使用一些与语义网相关的标签,例如{{3} }。即如果您有馆藏,则nextprevfirstlast对于分页或对于item对于专用项目来说是非常有意义的(并且已经在IANA上注册)在列表中。为了返回上一个集合,此集合可能先前已作为collection返回,或者由相应的项目指定。如果应该执行诸如添加或编辑之类的操作,则类似edit-form的链接关系可以告诉客户端URI将返回某种形式的格式,该格式将告诉客户端对API的请求看起来如何。

接下来,由于基本JSON在向客户提供帮助方面不是那么好,因为它所做的只是定义文档的语法结构,但缺乏对给定元素含义的支持,因此应该使用一些更高级的媒体类型支持的。正如Cassio和Exadra37所提到的,有两种基于JSON的文档类型提供对HATEOAS(〜URI和链接关系名称)的支持。与其仅使用schema.org,还不如使用多种文档类型,因为这会增加与许多支持其他媒体类型的不同客户端的互操作性。还要注意,返回HTML表示也没有错。 REST并不仅限于特定的JSON或XML内容。我想大多数时候,只需要使用HTML就足以将内容的含义从API传递到服务器,而不是指定自己的媒体类型。

您当然可以自由创建自己的媒体类型并使用它。但是,为了提高互操作性,您应该对其进行标准化,并且可能还为第三方框架提供插件/库,以便它们也能够使用您的格式。

不过,最好的建议当然是重用现有标准,因为其他客户已经熟悉此类实现或概念的可能性远高于自定义格式。除此之外,它还可能使您省去很多工作和精力。