JSON REST/RPC 接口的 IDL

Posted

技术标签:

【中文标题】JSON REST/RPC 接口的 IDL【英文标题】:IDL for JSON REST/RPC interface 【发布时间】:2012-06-02 10:09:09 【问题描述】:

我们正在设计一个相当复杂的 REST API,其中大部分 I/O 是具有特定结构的 JSON 编码对象。我们发现的一个挑战是以一种使客户更容易发布正确输入和处理输出的方式记录 API。由于输入和输出的数据都需要相当复杂的 JSON 对象,客户端开发者经常会引入与 I/O 对象结构相关的 bug。

现在有了所有 JSON Web API,我希望有一个通用的解决方案,但我很难找到一个。我查看了json-schema,这是一个 json 验证模式,但 IETF 草案和实现似乎都相当不成熟(即使它们已经存在了一段时间,这不是一个好兆头)。

Protocol Buffers 和Apache Avro 提供了一种稍微不同的方法,其中架构不用于验证,但实际上需要用于消息的编码/解码。在这 2 个中,Avro 的文档和实现似乎相当有限。 ProtoBuf 似乎更好,但我不确定这是否真的适合在浏览器中使用来调用 JSON api?

现在我开始怀疑我是否从正确的角度看待这个问题。是否有其他方法可以使我的 API 更加强类型?还是对 JSON REST/RPC API 的正式描述违背了使用 JSON 的目的?

编辑:在此主题后 6 个月,我们找到了 mongoose,这与我们正在寻找的内容非常接近。

【问题讨论】:

如果你真的需要使用现有的解决方案,我会选择 json-schema,它看起来很容易使用。否则,我认为自己检查 JSON 结构并不难——检查每个对象是否具有您需要的属性,如果您也有,则递归地执行此操作。与 XML 不同,JSON 的验证非常简单,这可能就是不存在合适的模式验证解决方案的原因。 【参考方案1】:

在我收到的 Douglas Crockford 的电子邮件回复下方。

我不相信模式可以替代输入验证。 有些属性无法从语法中验证。我想 这是 XML 出错的原因之一。

如果您的格式太复杂,那么我会考虑简化 他们。

【讨论】:

【参考方案2】:

存在这样的系统,我是其中之一的作者。它被称为Piqi-RPC,它对通过 HTTP 的 RPC 样式 API 的输入和输出参数进行基于 IDL 的验证。

它支持 JSON、XML 和 Google 协议缓冲区作为 HTTP POST 请求的输入和输出的数据表示格式。客户端可以选择使用这三种格式中的任何一种,并使用标准的AcceptContent-Type HTTP 标头指定他们的选择。

所以,是的,理论上,您正在寻找正确的方向。但是,目前 Piqi-RPC 仅支持在 Erlang 中编写服务器,如果您使用不同的堆栈,它对您来说并不是很有用。我听说 Apache Thrift 也支持 JSON over HTTP 传输,但我没有检查。我知道的另一种类似系统(也适用于 Erlang)称为UBF。我听说过可以基于 Protocol Buffers 规范解析和验证 JSON 的 Java 库(例如 http://code.google.com/p/protostuff/)。

这个想法本身远非新鲜事物,但在实践中并没有多少系统能够接近它。这是一个具有挑战性的问题。

从历史上看,IDL 用于接口定义和二进制数据序列化,而不是用于验证后来出现的动态数据交换格式(例如 XML 和 JSON)。 Sun-RPC IDL 和 CORBA IDL 属于第一类。 WSDL 将是涵盖这两个领域的少数示例之一,但它是一项糟糕的技术,对于大多数现代系统来说,这将是一个糟糕的选择。此外,还有许多模式语言(也称为 DDL——数据定义语言),其中大多数是高度专业化的,并且只使用一种表示格式,例如XML 或 JSON 模式。其中很少有稳定的实现。

Piqi project 和基于它的 Piqi-RPC 是围绕几个相当简单的实现构建的:

DLL 不必明确地绑定到任何特定的数据表示格式或围绕它构建。相反,这种语言可以相当普遍,涵盖广泛的实际用例(例如跨语言数据序列化和数据验证)和数据格式(例如 JSON、XML、Protocol Buffers)。

用于 RPC 式通信的 IDL 可以实现为通用 DDL 之上的一个薄的、主要是语法层。

此类 IDL 和接口规范可以与传输无关。

将基于 HTTP 的 REST 样式 API 与基于 HTTP 的 RPC 样式 API 进行比较。

使用 RPC 样式的 API,服务开发人员或自动化系统必须验证三件事:函数名称(根据某些服务命名方案)、输入以及(如果您选择)输出。

对于 REST 风格的 API,人们会无缘无故地陷入困境。现在,他们有更多的东西需要验证:任意复杂的 URL 语法,包括编码在 URL 段中的动态参数(适用于所有 HTTP 方法)和 URL 查询字符串(仅适用于 HTTP GET 方法)、HTTP 方法对应关系(是否应该是 GET、POST、PUT、DELETE 等)、某些参数到达那里时的 HTTP 正文(有时他们手动为 JSON 和 XML 表示的参数执行两次)、自定义 HTTP 标头以及单独的服务文档。想象一下支持所有这些的 IDL!

【讨论】:

【参考方案3】:

XML 在很多方面更适合 RESTful 服务。它具有原生链接(<link href=,适用于所有HATEOAS 粉丝)、原生语言支持(lang="en")和强大的生态系统。

它也更适合未来的验证和未来的 API 重构。转换这个:

<profile>
    <username>alganet</username>
</profile>

支持更多用户名:

<profile>
    <username>alganet</username>
    <username>alexandre</username>
</profile>

在不破坏现有客户端的情况下使用 XML 更简单。 JSON 很难做到这一点。

如果您真的需要 JSON,JSON-Schema 是您的最佳选择。它不成熟,但我不知道关于那个案子有什么更好的。也许您的消费者可以在 XML 和 JSON 之间进行选择,因此他们可以使用 Content Negotiation 在小型负载 (JSON) 或 RESTful candies (XML) 之间进行选择。

【讨论】:

【参考方案4】:

我会说你最后一个问题的答案是肯定的。如果您需要一种方法来约束和记录 JSON“模式”,为什么不首先使用 XML?解析起来并没有那么难,并且能够为其强制执行模式是一个很大的优势。

【讨论】:

以上是关于JSON REST/RPC 接口的 IDL的主要内容,如果未能解决你的问题,请参考以下文章

从外部类型库导入 IDL 中的接口

将 rmi 接口转换为 CORBA .idl

使用大量 IDL 接口管理 COM 类型库中的定义

HarmonyOS之IDL接口使用规范

为啥接口上的“添加 IDL 方法”将方法添加到模块以及 CoClass?

SOA,Webservice,SOAP,REST,RPC,RMI的区别与联系