我试图在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不需要任何额外的工作或设置就可以使用响应代码、报头、查询、帖子正文、缓存和许多其他特性。
当前回答
我过去一直是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
其他回答
首先,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
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方面还有更多的区别和优势。
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%的情况下应该走的路线。
祝你好运, 迈克
我使用vdata为RPC协议: http://vdata.dekuan.org/
1、PHP和JavaScript都没问题。 2、跨源资源共享(CORS)呼叫仍然正常。
我已经对这个问题进行了一些详细的研究,并认为纯REST的局限性太大,RPC是最好的,尽管我的大多数应用程序都是CRUD应用程序。如果您坚持使用REST,那么您最终将会挠头思考如何轻松地将另一个所需的方法添加到API中以实现某些特殊目的。在许多情况下,使用REST实现这一点的唯一方法是为它创建另一个控制器,这可能会使程序过于复杂。
如果您决定使用RPC,唯一的区别是您显式地将动词指定为URI的一部分,这是清晰的、一致的、bug较少的,而且确实没有麻烦。特别是如果你要创建一个超越简单CRUD的应用程序,RPC是唯一的选择。我对REST的纯粹主义者还有另一个问题:HTTP POST, GET, PUT, DELETE在HTTP中有明确的含义,这些含义被REST颠覆为其他含义,仅仅是因为它们在大多数时间都适用——但不是所有时间都适用。
在编程中,我很久以前就发现,试图用一件事来表示两件事,有时会让你吃不厌。我喜欢能够对几乎每个操作都使用POST,因为它提供了按方法需要发送和接收数据的自由。你不能把整个世界都放进CRUD里。