我试图在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。

这些观点大多是有争议的,完全取决于一个人的需要。

其他回答

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%的情况下应该走的路线。

祝你好运, 迈克

为什么JSON RPC:

对于REST api,我们必须为可能需要的每个功能/方法定义一个控制器。因此,如果我们想让客户端访问10个方法,我们就必须编写10个控制器来将客户端请求连接到特定的方法。

另一个因素是,即使我们为每个方法/功能使用不同的控制器,客户端也必须记住是使用POST还是GET。这使事情更加复杂。为了发送数据,如果使用POST,则必须设置请求的内容类型。

对于JSONRPC,事情大大简化了,因为大多数JSONRPC服务器操作POST HTTP方法,内容类型始终是application/ JSON。这减轻了在客户端使用正确的HTTP方法和内容设置的负担。

不必为服务器想要向客户端公开的不同方法/功能创建单独的控制器。

为什么休息:

对于服务器希望向客户端公开的不同功能,有不同的url。因此,您可以嵌入这些url。

这些观点大多是有争议的,完全取决于一个人的需要。

我过去一直是REST的忠实粉丝,它在纸上比RPC有很多优势。你可以给客户端提供不同的内容类型、缓存、HTTP状态代码的重用,你可以通过API引导客户端,如果API不是大部分都是自解释的,你可以在API中嵌入文档。

But my experience has been that in practice this doesn't hold up and instead you do a lot of unnecessary work to get everything right. Also the HTTP status codes often don't map to your domain logic exactly and using them in your context often feels a bit forced. But the worst thing about REST in my opinion is that you spend a lot of time to design your resources and the interactions they allow. And whenever you do some major additions to your API you hope you find a good solution to add the new functionality and you didn't design yourself into a corner already.

This often feels like a waste of time to me because most of the time I already have a perfectly fine and obvious idea about how to model an API as a set of remote procedure calls. And if I have gone through all this effort to model my problem inside the constraints of REST the next problem is how to call it from the client? Our programs are based on calling procedures so building a good RPC client library is easy, building a good REST client library not so much and in most cases you will just map back from your REST API on the server to a set of procedures in your client library.

正因为如此,今天对我来说,RPC感觉更简单、更自然。不过,我真正怀念的是一个一致的框架,它可以很容易地编写自描述和可互操作的RPC服务。因此,我创建了自己的项目,尝试新的方法使RPC对我自己更容易,也许其他人也会发现它有用:https://github.com/aheck/reflectrpc

如果您的服务只使用模型和GET/POST/PUT/DELETE模式就能正常工作,那么请使用纯REST。

我同意HTTP最初是为无状态应用程序设计的。

但是对于现代的、更复杂的(!)实时(web)应用程序,你想要使用Websockets(这通常意味着有状态性),为什么不同时使用呢?基于Websockets的JSON-RPC非常简单,所以你有以下好处:

在每个客户机上进行即时更新(为更新模型定义您自己的服务器到客户机RPC调用) 容易增加复杂性(尝试只使用REST制作Etherpad克隆) 如果你做得对(只添加RPC作为实时的额外功能),大多数仍然可以使用REST(除非主要功能是聊天或其他)

由于您只是在设计服务器端API,所以从定义REST模型开始,然后根据需要添加JSON-RPC支持,将RPC调用的数量保持在最低限度。

(很抱歉括号用多了)

在我看来,关键在于行动vs资源导向。REST是面向资源的,非常适合CRUD操作,并且由于其已知的语义为第一个用户提供了一些可预测性,但是当从方法或过程实现时,将迫使您提供对以资源为中心的世界的人工转换。另一方面,RPC非常适合面向操作的api,在这种api中,您公开的是服务,而不是可用于RPC的资源集。

毫无疑问REST更受欢迎,如果你想将API公开给第三方,这无疑会增加一些好处。

如果不是(例如在SPA中创建AJAX前端),我的选择是RPC。特别是JSON- rpc,结合JSON Schema作为描述语言,并根据用例通过HTTP或Websockets传输。

JSON-RPC是一个简单而优雅的规范,它定义了用于同步或异步RPC的请求和响应JSON有效负载。

JSON Schema是一份规范草案,定义了一种基于JSON的格式,旨在描述JSON数据。通过使用JSON Schema描述您的服务输入和输出消息,您可以在消息结构中拥有任意的复杂性,而不会影响可用性,并且可以自动化服务集成。

传输协议(HTTP vs websockets)的选择取决于不同的因素,最重要的是你是否需要HTTP特性(缓存、重新验证、安全性、幂等性、内容类型、多部分等等),或者你的应用程序是否需要在高频率下交换消息。

到目前为止,这主要是我个人对这个问题的看法,但是现在有一些东西可以真正帮助那些阅读这些行的Java开发人员,我在过去的一年里一直在工作的框架,诞生于你现在想知道的同一个问题:

http://rpc.brutusin.org

你可以在这里看到一个现场演示,展示了用于功能测试的内置存储库浏览器(感谢JSON Schema)和一系列示例服务:

http://demo.rpc.brutusin.org

希望对伴侣有帮助!

Nacho