REST存在很多困惑和误解。不幸的是,我们更常见到的是那些做的与REST相反的应用程序自称为RESTful,而不是真正的REST应用程序。
“从我所了解的来看,它只是API中函数的约定吗?”
不,REST不仅仅是API内部函数的约定,也不像其他答案中所说的直接与SOAP或HTTP相关。REST是一种软件架构风格,受到Web本身成功设计决策的启发。简单来说,REST API应该像网站一样工作。
当您进入一个网站时,您会进入一个主页,了解这个网站的内容,并且HTML文档将有超链接指向您需要的资源。唯一的外带信息是资源本身的媒体类型,而不是如何找到它们。例如,当您进入StackOverflow时,您知道问题和答案是什么,并寻找指向它们的链接。您的浏览器如何呈现这些链接,您如何选择并跟随它们与其他网站(如电子邮件或新闻网站)并没有区别。使其不同的是您要获取的资源的媒体类型。
这就是REST API应该工作的方式。客户端不应依赖除详细说明资源功能以外的任何外带信息。他们应连接到返回链接的主页,以执行所需的操作。如果API没有这样做,则它不是REST。简而言之。
我喜欢称这些API为“街头REST”,因为人们经常通过复制其他自称为REST的API中看到的内容以及其他人谈论REST的方式来实现它们。
“所有函数都应该是GET / POST / DELETE / PUT形式吗?”
这是一个常见的困惑,您会看到很多这样的情况,包括将其与CRUD操作混淆,或者REST不允许任何其他动词等。那是胡说八道。
REST独立于任何特定的协议,因此说函数应遵循HTTP方法是没有意义的。REST将您的应用程序约束为统一接口,这意味着无论使用什么协议,您都必须尽可能地遵循标准化行为。如果您正在使用HTTP实现REST应用程序,则这意味着您的API必须遵循客户端-服务器交互的HTTP方法,这意味着您不能像某些使用HTTP的应用程序一样发明其他HTTP方法。如果更改通信协议,则客户端需要在进入API之前了解该信息,这是更多的外带信息。
如何在代码中实现这一点与REST无关。REST不是开发模式或哲学,而是一种架构风格。
“我主要是困惑JSON / XML在其中扮演的角色?”
JSON / XML是REST API中传输数据的格式。客户端向服务器发出请求后,服务器将响应以JSON / XML格式返回。这些格式使得数据易于解析和处理,并且与REST的无状态性质相匹配。
这里也存在很多混淆。在REST应用中,您应该定义具有描述所需所有行为的
状态的抽象实体。 API将用作客户端和服务器之间传输这些实体的媒体类型
表示的通道。 REST代表表述性状态转移。客户端请求的URI是该资源的标识符,该请求的元数据将告诉服务器客户端准备接受哪些媒体类型。 JSON / XML根本不直接参与REST。它们只是一种表示媒体类型,对于计算机来说比如text / html等格式更容易解析和获取信息,旨在由浏览器呈现供人类可视化。
例如,以StackOverflow本身为例。抽象意义上的问题是什么?这是一个请求信息的要求。如何正式定义该抽象资源?有作者,正在提出的问题的实际文本,顶部和底部,评论和可能的答案等,所有这些都是具有自己定义的抽象资源。实际数据存储在某个数据库中,当您请求主页时,它会返回带有标识这些问题的URI的链接。以此问题为例,它具有URI
http://stackoverflow.com/questions/24092517
。当我想在我的浏览器上渲染漂亮的文档中阅读该问题时,我将请求该URI,但是通过
Accept
标头告诉服务器我想要一个
text / html
表示,并且我的浏览器知道如何将HTML呈现为漂亮的页面。另一方面,当我想要请求该问题以将其存储回数据库时,我不需要渲染漂亮的文档页面所需的所有可爱内容,因此我要求更容易解析并且不包含大量不必要信息的格式,例如JSON或XML。
大多数构建街道REST API的人都了解这一点,但他们错过了最有趣的部分,即您不限于已经存在的媒体类型。您可以创建仅存在于API或公司应用程序生态系统中的私有媒体类型。因此,例如,而不是将所有JSON文档的媒体类型称为
application / json
,无论其中的内容如何,我们可以拥有反映特定资源类型的自定义媒体类型。因此,我们可以在JSON格式中表示StackOverflow问题的
application / vnd.stackoverflow.question.v1 + json
。一旦做到这一点,您就不必浪费时间记录通信协议已标准化的操作,而应专注于记录该自定义媒体类型以及如何与之交互,独立于通信协议。一旦您清楚了这一点,客户端就可以使用任何可用的协议与您的服务进行交互。
如果您理解了这三个主要点,您就能理解REST的含义。通过使用超链接作为应用程序状态引擎,您不会被绑定到实现的任何特定时间点。您的服务器可以随意发展,您可以随意更改URI,而客户端不会出现问题。通过遵循标准化协议,通用客户端更容易使用您的API,更不用说如果他们已经知道您不会破坏协议,那么开发人员更容易理解如何集成。通过将设计和文档编制工作集中在媒体类型上,而不是协议细节和URI语义上,您可以避免引入更多驱动API所需的带外信息,并且您的客户端也更具有弹性来应对变化。