我试图在REST和JSON-RPC之间做出选择,为web应用程序开发API。它们是如何比较的?
更新2015:我发现REST在Web/HTTP上的API上更容易开发和使用,因为API可以利用客户端和服务器都理解的现有和成熟的HTTP协议。例如,API不需要任何额外的工作或设置就可以使用响应代码、报头、查询、帖子正文、缓存和许多其他特性。
我试图在REST和JSON-RPC之间做出选择,为web应用程序开发API。它们是如何比较的?
更新2015:我发现REST在Web/HTTP上的API上更容易开发和使用,因为API可以利用客户端和服务器都理解的现有和成熟的HTTP协议。例如,API不需要任何额外的工作或设置就可以使用响应代码、报头、查询、帖子正文、缓存和许多其他特性。
当前回答
为什么JSON RPC:
对于REST api,我们必须为可能需要的每个功能/方法定义一个控制器。因此,如果我们想让客户端访问10个方法,我们就必须编写10个控制器来将客户端请求连接到特定的方法。
另一个因素是,即使我们为每个方法/功能使用不同的控制器,客户端也必须记住是使用POST还是GET。这使事情更加复杂。为了发送数据,如果使用POST,则必须设置请求的内容类型。
对于JSONRPC,事情大大简化了,因为大多数JSONRPC服务器操作POST HTTP方法,内容类型始终是application/ JSON。这减轻了在客户端使用正确的HTTP方法和内容设置的负担。
不必为服务器想要向客户端公开的不同方法/功能创建单独的控制器。
为什么休息:
对于服务器希望向客户端公开的不同功能,有不同的url。因此,您可以嵌入这些url。
这些观点大多是有争议的,完全取决于一个人的需要。
其他回答
RPC的基本问题是耦合。RPC客户端以多种方式与服务实现紧密耦合,在不破坏客户端的情况下更改服务实现变得非常困难:
客户需要知道过程名称; 程序参数顺序,类型和计数事项。在不破坏客户端实现的情况下,在服务器端改变过程签名(参数的数量、参数的顺序、参数类型等)并不是那么容易的; RPC样式只公开过程端点+过程参数。客户不可能决定下一步该做什么。
另一方面,在REST风格中,通过在表示(HTTP报头+表示)中包含控制信息来引导客户端是非常容易的。例如:
It's possible (and actually mandatory) to embed links annotated with link relation types which convey meanings of these URIs; Client implementations do not need to depend on particular procedure names and arguments. Instead, clients depend on message formats. This creates possibility to use already implemented libraries for particular media formats (e.g. Atom, HTML, Collection+JSON, HAL etc...) It's possible to easily change URIs without breaking clients as far as they only depend on registered (or domain specific) link relations; It's possible to embed form-like structures in representations, giving clients the possibility to expose these descriptions as UI capabilities if the end user is human; Support for caching is additional advantage; Standardised status codes;
在REST方面还有更多的区别和优势。
首先,HTTP-REST是一种“具象状态传输”体系结构。这意味着很多有趣的事情:
您的API将是无状态的,因此更容易设计(在复杂的自动机中很容易忘记转换),并与独立的软件部件集成。 你将被引导设计安全的读取方法,这将是容易缓存和集成。 你会被引导把写方法设计成幂等的方法,这样可以更好地处理超时。
其次,HTTP- rest完全兼容HTTP(请参阅前一部分中的“安全”和“幂等”),因此您将能够重用HTTP库(适用于所有现有语言)和HTTP反向代理,这将使您能够实现高级功能(缓存、身份验证、压缩、重定向、重写、日志记录等),而无需代码行。
最后但并非最不重要的是,根据HTTP 1.1的设计者(以及REST的发明者)的说法,使用HTTP作为RPC协议是一个巨大的错误:http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_5_2
错误的问题:强加一个根本不存在的摩尼教!
您可以使用带有“较少动词”(没有方法)的JSON-RPC,并保留sendo id、参数、错误代码和警告消息所需的最小标准化。JSON-RPC标准没有说“你不能是REST”,只是说如何打包基本信息。
“REST JSON-RPC”存在!是REST与“最佳实践”,最小化信息包装,简单可靠的合同。
例子
(从这个答案和教学上下文)
在处理REST时,从资源的角度考虑通常会有所帮助。在这种情况下,资源不仅仅是“银行账户”,而是该银行账户的交易……但是JSON-RPC没有指定“方法”参数,所有都是由端点的“路径”编码的。
REST Deposit with POST /Bank/Account/John/Transaction with JSON request {"jsonrpc": "2.0", "id": 12, "params": {"currency":"USD","amount":10}}. The JSON response can be something as {"jsonrpc": "2.0", "result": "sucess", "id": 12} REST Withdraw with POST /Bank/Account/John/Transaction ... similar. ... GET /Bank/Account/John/Transaction/12345@13 ... This could return a JSON record of that exact transaction (e.g. your users generally want a record of debits and credits on their account). Something as {"jsonrpc": "2.0", "result": {"debits":[...],"credits":[...]}, "id": 13}. The convention about (REST) GET request can include encode of id by "@id", so not need to send any JSON, but still using JSON-RPC in the response pack.
为什么JSON RPC:
对于REST api,我们必须为可能需要的每个功能/方法定义一个控制器。因此,如果我们想让客户端访问10个方法,我们就必须编写10个控制器来将客户端请求连接到特定的方法。
另一个因素是,即使我们为每个方法/功能使用不同的控制器,客户端也必须记住是使用POST还是GET。这使事情更加复杂。为了发送数据,如果使用POST,则必须设置请求的内容类型。
对于JSONRPC,事情大大简化了,因为大多数JSONRPC服务器操作POST HTTP方法,内容类型始终是application/ JSON。这减轻了在客户端使用正确的HTTP方法和内容设置的负担。
不必为服务器想要向客户端公开的不同方法/功能创建单独的控制器。
为什么休息:
对于服务器希望向客户端公开的不同功能,有不同的url。因此,您可以嵌入这些url。
这些观点大多是有争议的,完全取决于一个人的需要。
Great answers - just wanted to clarify on a some of the comments. JSON-RPC is quick and easy to consume, but as mentioned resources and parameters are tightly coupled and it tends to rely on verbs (api/deleteUser, api/addUser) using GET/ POST where-as REST provides loosely coupled resources (api/users) that in a HTTP REST API relies on several HTTP methods (GET, POST, PUT, PATCH, DELETE). REST is slightly harder for inexperienced developers to implement, but the style has become fairly common place now and it provides much more flexibility in the long-run (giving your API a longer life).
除了没有紧密耦合的资源外,REST还允许您避免提交到单一的内容类型中——这意味着如果您的客户端需要接收XML、JSON甚至YAML格式的数据——如果在您的系统中,您可以使用内容类型/接受标头返回其中任何一种。
这让你的API足够灵活,以支持新的内容类型或客户端需求。
But what truly separates REST from JSON-RPC is that it follows a series of carefully thought out constraints- ensuring architectural flexibility. These constraints include ensuring that the client and server are able to evolve independently of each other (you can make changes without messing up your client's application), the calls are stateless (state is represented through hypermedia), a uniform interface is provided for interactions, the API is developed on a layered system, and the response is cacheable by the client. There's also an optional constraint for providing code on demand.
然而,尽管如此,大多数API都不是RESTful的(根据Fielding的说法),因为它们不包含超媒体(在响应中嵌入超文本链接,帮助导航API)。大多数api都是类似REST的,因为它们遵循大多数REST的概念,但忽略了这个约束。然而,越来越多的api正在实现这一点,它正在成为一种主流实践。
这也为您提供了一些灵活性,因为超媒体驱动的api(如Stormpath)将客户端引导到URI(这意味着如果某些情况发生了变化,在某些情况下您可以修改URI而不会产生负面影响),而与RPC一样,URI需要是静态的。使用RPC,您还需要广泛地记录这些不同的uri,并解释它们如何相互关联地工作。
一般来说,如果您想要构建一个可扩展的、灵活的、长期存在的API,我认为REST是最佳选择。基于这个原因,我认为这是99%的情况下应该走的路线。
祝你好运, 迈克