关于graphql:REST vs JSON-RPC?

REST vs JSON-RPC?

我试图在REST和JSON-RPC之间进行选择,以便为Web应用程序开发API。哪一个更容易用于API客户机?

Update 2015: I have found REST easier to develop and use for an API which is served on Web/HTTP, because the existing and mature HTTP protocol which is understood by both client and server can be leveraged by the API. For example response codes, headers, queries, post bodies, caching and many other features can be used by the API without any additional effort or setup.


RPC的基本问题是耦合。RPC客户机以多种方式与服务实现紧密耦合,在不破坏客户机的情况下更改服务实现变得非常困难:

  • 要求客户知道程序名称;
  • 程序参数顺序、类型和计数事项。在不破坏客户端实现的情况下,在服务器端更改过程签名(参数数量、参数顺序、参数类型等)并不容易;
  • rpc样式只公开过程终结点+过程参数。客户不可能确定下一步要做什么。

另一方面,在REST样式中,通过在表示(HTTP头+表示)中包含控制信息,很容易引导客户机。例如:

  • 有可能(实际上是强制性的)嵌入带有链接关系类型注释的链接,这些链接传递了这些URI的含义;
  • 客户端实现不需要依赖于特定的过程名和参数。相反,客户机依赖于消息格式。这就有可能将已经实现的库用于特定的媒体格式(例如Atom、HTML、Collection+JSON、HAL等)。
  • 只要客户机只依赖于注册的(或特定于域的)链接关系,就可以在不破坏客户机的情况下轻松地更改URI;
  • 在表示中嵌入类似表单的结构是可能的,如果最终用户是人类,客户机就有可能将这些描述作为用户界面功能公开;
  • 对缓存的支持是额外的优势;
  • 标准化状态代码;

其他方面还有很多不同和优势。


我对这个问题做了一些详细的探讨,并认为纯REST太有限了,而RPC是最好的,尽管我的大多数应用程序都是CRUD应用程序。如果你坚持休息,你最终会抓耳挠腮,想知道如何为某些特殊目的向你的API添加另一个需要的方法。在许多情况下,使用REST实现这一点的唯一方法是为它创建另一个控制器,这可能会使程序过于复杂。

如果您决定使用rpc,唯一的区别是您显式地将动词指定为uri的一部分,这是清晰的、一致的、不太麻烦的,而且实际上没有问题。尤其是如果您创建的应用程序远远超出了简单的CRUD,那么RPC是唯一的方法。我还有另外一个问题是,RESTful的纯粹主义者:http post、get、put、delete在http中有明确的含义,这些含义被REST所颠覆,变成了其他含义,仅仅是因为它们适合大多数时间——但并非所有时间。

在编程中,我早就发现,试图用一件事来表示两件事,有时会出现,并咬你。我喜欢在几乎每一个操作中使用post,因为它提供了发送和接收数据的自由,正如您的方法所需要的那样。你不能把整个世界都塞进积垢里。


首先,HTTP-REST是一种"代表性状态传输"体系结构。这意味着很多有趣的事情:

  • 您的API将是无状态的,因此更容易设计(在复杂的自动机中很容易忘记转换),并与独立的软件部分集成。
  • 您将引导您将读取方法设计为安全的方法,这将易于缓存和集成。
  • 您将被引导到将写方法设计为等量方法,这将更好地处理超时问题。

第二,HTTP-REST完全兼容HTTP(参见前一部分中的"安全"和"等幂"),因此您将能够重用HTTP库(现有的每种语言)和HTTP反向代理,这将使您能够实现高级功能(缓存、身份验证、压缩、重定向、重写、日志记录、E代码行为零。

最后但并非最不重要的是,根据HTTP 1.1的设计者(以及REST的发明者)的说法,将HTTP用作RPC协议是一个巨大的错误:http://www.ics.uci.edu/~fielding/pubs/document/evaluation.htm sec_6_5_2


很好的答案-只是想澄清一些评论。JSON-RPC是快速且易于使用的,但是正如前面提到的,资源和参数是紧密耦合的,它往往依赖于使用get/post的动词(api/deleteuser、api/adduser),其中as rest提供松散耦合的资源(api/users),而在http rest api中依赖于几个http方法(get、post、put、patch、delete)。对于缺乏经验的开发人员来说,REST稍微难一些实现,但是样式现在已经变得相当常见,并且从长远来看,它提供了更多的灵活性(使您的API具有更长的寿命)。

除了没有紧密耦合的资源之外,REST还允许您避免被提交到单个内容类型——这意味着如果您的客户机需要接收XML、JSON甚至YAML格式的数据——如果您的系统内置了这些数据,那么您可以返回使用Content-Type/Accept头的任何一个数据。

这使您的API足够灵活,可以支持新的内容类型或客户机需求。

但真正将REST与JSON-RPC分开的是,它遵循一系列经过仔细考虑的约束——确保体系结构的灵活性。这些约束包括确保客户机和服务器能够彼此独立地发展(您可以在不干扰客户机应用程序的情况下进行更改)、调用是无状态的(状态通过超媒体表示)、为交互提供统一的接口、在分层系统上开发API以及响应ONSE可由客户端缓存。还有一个可选的约束,用于按需提供代码。

然而,尽管如此,大多数API都不是静止的(根据Fielding的说法),因为它们不包含超媒体(响应中嵌入的超文本链接有助于导航API)。您将发现的大多数API都像REST一样遵循REST的大多数概念,但忽略这个约束。然而,越来越多的API正在实现这一点,并且它越来越成为主流实践。

这也为您提供了一些灵活性,因为超媒体驱动的API(如stormpath)将客户机引导到uri(也就是说,如果有什么变化,在某些情况下,您可以在不产生负面影响的情况下修改uri),其中与rpc uri一样,需要是静态的。使用RPC,您还需要广泛地记录这些不同的URI,并解释它们如何相互关联。

一般来说,如果您想要构建一个可扩展的、灵活的、长寿命的API,那么REST就是您要做的事情。因为这个原因,我会说这是99%的时间去的路线。

祝你好运,迈克


如果您的服务只适用于模型和get/post/put/delete模式,请使用pure rest。

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

但对于现代人来说,更复杂!实时(Web)应用程序,您希望在其中使用WebSockets(这通常意味着状态性),为什么不同时使用两者呢?WebSockets上的JSON-RPC非常轻,因此您有以下好处:

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

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

(很抱歉括号使用过度)


海事组织,the key is the action VS资源定位点。休息是好的资源对象和操作和crud FITS known for its given to some predictability语义提供了当用户在第一,但你要实现的方法或程序从提供安队和translation to the资源为中心的世界。on the other手套装perfectly to action对象的RPC服务的API,你在哪里,不是暴露,可以crud资源集合。P></

毫无疑问这是流行的黑莓休息,当然如果你想adds some points to the API暴露在第三方。P></

if not(for example of creating安在房屋前端ajax在温泉),我的选择是相似的。特别的JSON RPC模式,联合与AS和description language,transported过websockets depending on the使用HTTP或房屋。P></

RPC是简单和优雅,defines request和response JSON规范有效载荷to be used in同步或异步的RPC。P></

JSON规范模式是基于在选秀defining JSON格式aimed AT describing JSON数据。你的服务的输入和输出模式describing messages使用JSON,你可以有一个任意模式的复杂性也在the message结构没有compromising usability和服务一体化,可以自动化。P></

the circle of运输协议(HTTP)的不同depends VS websockets)最重要的因素,你是否有需要的特点(HTTP缓存,内容安全,revalidation,幂等性,多型,或是否你,…)的应用在高frecuencies needs to交换消息。P></

直到现在,我认为它是非常个人的问题现在something on the,but that can be for Java真的帮助到那些阅读这些developers the Lines,我一直工作在框架由the last from the same question年出世,现在你想知道:P></

http://rpc.brutusin.orgP></

你可以看到现场演示在这里,showing the库建立功能测试(thanks for JSON浏览器模式)和系列服务:example ofP></

http://demo.rpc.brutusin.orgP></

希望它helps伴侣!P></

纳乔P></


我过去一直是REST的忠实粉丝,它比纸质的RPC有很多优势。您可以向客户机展示不同的内容类型、缓存、重用HTTP状态代码、指导客户机通过API,如果API中的文档大部分都不是自解释的,您还可以将其嵌入到API中。

但我的经验是,在实践中,这并没有阻碍,相反,你做了很多不必要的工作来让一切都好起来。另外,HTTP状态代码通常无法准确映射到域逻辑,在您的上下文中使用它们通常会感到有点强迫。但在我看来,休息最糟糕的是你花了很多时间来设计你的资源和它们允许的交互。每当你对你的API做一些重要的添加时,你希望你能找到一个好的解决方案来添加新的功能,而且你还没有设计好自己。

对于我来说,这常常是浪费时间,因为大多数时候我已经对如何将API建模为一组远程过程调用有了一个完美而明显的想法。如果我已经完成了所有这些工作,在REST的约束内对我的问题进行建模,那么下一个问题是如何从客户机调用它?我们的程序基于调用过程,因此构建一个好的RPC客户机库很容易,构建一个好的REST客户机库就不那么容易了,在大多数情况下,您只需将服务器上的REST API映射回客户机库中的一组过程。

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


根据Richardson成熟度模型,问题不是REST和RPC,而是有多少REST?

从这个角度来看,对REST标准的遵从性可以分为4个级别。

  • 0级:从行动和参数方面考虑。正如本文所解释的,这基本上等同于JSON-RPC(本文解释它是针对XML-RPC的,但两个参数相同)。
  • 一级:从资源角度考虑。与资源相关的所有内容都属于同一个URL
  • 级别2:使用HTTP谓词
  • 三级:仇恨

根据REST标准的创建者,只有级别3的服务可以称为RESTful。然而,这是一个符合性的度量标准,而不是质量。如果您只想调用一个执行计算的远程函数,那么在响应中使用相关的超媒体链接可能是没有意义的,这两种行为都没有根据所使用的HTTP动词进行区分。因此,这样的调用本质上更像RPC。但是,较低的遵从性级别并不一定意味着状态性或较高的耦合性。也许,您不应该考虑REST和RPC,而是应该尽可能多地使用REST,但不要再使用了。不要为了符合RESTful遵从性标准而扭曲应用程序。


为什么选择JSON RPC:

对于RESTAPI,我们必须为可能需要的每个功能/方法定义一个控制器。因此,如果我们有10个方法希望客户机能够访问,那么我们必须编写10个控制器来将客户机的请求与特定方法进行接口。

另一个因素是,尽管我们对每个方法/功能都有不同的控制器,但是客户机必须记住是使用POST还是GET。这使事情更加复杂。除此之外,如果要发送数据,还必须设置请求的内容类型(如果使用post)。

在JSONRPC的情况下,事情会大大简化,因为大多数JSONRPC服务器都使用PostHTTP方法,内容类型始终是application/json。这将减轻记住在客户端使用适当的HTTP方法和内容设置的负担。

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

为什么休息:

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

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


我想,和往常一样,这取决于…

REST具有广泛的公众支持的巨大优势,这意味着需要大量的工具和书籍。如果您需要制造一个被来自不同组织的大量消费者使用的API,那么这是一种可行的方法,原因只有一个:它很流行。作为协议,它当然是完全失败的,因为有太多完全不同的方法可以将命令映射到url/verb/response。

因此,当你编写一个需要与后端对话的单页Web应用程序时,我认为REST太复杂了。在这种情况下,您不必担心长期的兼容性,因为应用程序和API可以一起进化。

我曾经为一个单页的Web应用程序开始休息,但是Web应用程序和服务器之间的细粒度命令很快让我发疯。我应该将其编码为路径参数吗?在尸体里?查询参数?一个标题?在URL /动词/响应设计之后,我必须在JavaScript中编码这种混乱,Java中的解码器,然后调用实际方法。尽管有很多工具可以使用,但是在域代码中不使用任何HTTP语义是非常困难的,这是非常糟糕的做法。(凝聚力)

尝试为一个中等复杂的站点制作一个昂首阔步的文件,并将它与描述该文件中远程过程的单个Java接口进行比较。复杂性的增加是惊人的。

因此,我将单页webapp从rest切换到json-rpc。AI开发了一个小的库,它在服务器上编码Java接口并将其传送到浏览器。在浏览器中,这为应用程序代码创建了一个代理,该代理为每个函数返回了一个承诺。

同样,休息也有它的位置,因为它是著名的,因此得到了很好的支持。认识到底层的无状态资源哲学和层次模型也很重要。然而,这些原则也可以很容易地在RPC模型中使用。JSONRPC工作于HTTP之上,因此它在这方面具有与REST相同的优势。不同之处在于,当你不可避免地遇到这些不符合这些原则的函数时,你就不会被迫做很多不必要的工作。


错误的问题:强加一个不存在的摩尼教!

您可以使用带有"less verb"(无方法)的JSON-RPC,并保留sendo id、参数、错误代码和警告消息所需的最小标准化。JSON-RPC标准没有说"你不能休息",只说如何打包基本信息。

"rest json-rpc"存在!剩下的就是"最佳实践",即最少的信息打包,以及简单而可靠的合同。

例子

(从这个答案和教学上下文)

在处理休息时,从资源的角度出发通常会有所帮助。在这种情况下,资源不仅仅是"银行账户",而是该银行账户的交易……但是json-rpc并不强制使用"method"参数,所有参数都由端点的"path"编码。

  • 根据JSON要求,向POST /Bank/Account/John/Transaction支付剩余存款。
    json响应可以是{"jsonrpc":"2.0","result":"sucess","id": 12}之类的。

  • 其余用POST /Bank/Account/John/Transaction退出…类似。

  • GET /Bank/Account/John/Transaction/12345@13…这可能会返回该确切事务的JSON记录(例如,您的用户通常希望在其帐户上记录借记和贷记)。类似于{"jsonrpc":"2.0","result": {"debits":[...],"credits":[...]},"id": 13}的东西。关于(rest)get请求的约定可以包括由"@id"对id进行编码,因此不需要发送任何JSON,但仍然在响应包中使用JSON-RPC。


HTTP是tightly偶联与休息,如果你只知道我过你的HTTP API暴露更多的适当的休息(but for most is not的情况)。不管一个人多,if You need to expose过你的API或其他运输类信息网站,那么你sockets is not just适用。P></


如果您请求资源,那么RESTfulAPI在设计上更好。如果您请求一些复杂的数据,其中包含许多参数和复杂的方法,而不是简单的CRUD,那么RPC是正确的方法。


最好在rest和json-rpc之间选择json-rpc,以便为更容易理解的Web应用程序开发API。JSON-RPC是首选的,因为它对方法调用和通信的映射很容易理解。

选择最合适的方法取决于约束条件或主要目标。例如,就性能是主要特性而言,建议使用JSON-RPC(例如,高性能计算)。但是,如果主要目标是不可知论者,以便提供一个可由其他人推断的通用接口,那么最好还是休息一下。如果需要实现这两个目标,建议同时包含这两个协议。

实际上,JSON-RPC将REST与之分离的事实是,它跟踪了一系列经过仔细考虑的约束——确认了体系结构的灵活性。这些约束确保客户机和服务器能够彼此独立地增长(可以在不干扰客户机应用的情况下进行更改),调用是无状态的(状态被视为超媒体),为交互提供统一的接口,API在分层系统上是高级的(Hall,2010)。.json-rpc快速且易于使用,但是正如前面提到的,资源和参数是紧密耦合的,它可能依赖于使用get/post的动词(api/adduser、api/deleteuser),而rest在http中提供松散耦合的资源(api/users)。RESTAPI依赖于几种HTTP方法,如get、put、post、delete、patch。对于缺乏经验的开发人员来说,REST稍微难一些。

JSON(表示为javascript对象表示法)是一种轻量级的数据交换格式,对于人类来说,它很容易读写。对于机器来说,解析和生成是非常简单的。JSON是一种完全独立于语言的文本格式,但它对C语言、C语言、C++语言、Java语言、Perl语言、JavaScript语言、Python语言以及许多其他语言的程序员都熟知。这样的属性使JSON成为一种完美的数据交换语言,是一种更好的选择。


我将vdata用于RPC协议:网址:http://vdata.dekuan.org/

1、PHP和javascript都可以。2,跨源资源共享(CORS)调用仍然可以。