用于 JSON REST/RPC 接口的 IDL



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

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

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

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

编辑:在这个话题6个月后,我们发现了猫鼬,这与我们正在寻找的非常接近。

下面是我从道格拉斯·克罗克福德(Douglas Crockford)通过电子邮件收到的回复。

我不相信模式是输入验证的替代方案。 有些属性无法从语法中验证。我认为 这是XML出错的方式之一。

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

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

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

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

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

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

Piqi

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

  • DLL 不必显式绑定到任何特定的数据表示格式或围绕它构建。相反,这种语言可以相当通用,涵盖广泛的实际用例(例如跨语言数据序列化和数据验证)和数据格式(例如JSON,XML,协议缓冲区)。

  • 用于 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!

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之间进行选择,因此他们可以使用内容协商在小有效负载(JSON)或RESTful糖果(XML)之间进行选择。

我会

说你最后一个问题的答案是肯定的。如果您需要一种方法来约束和记录JSON"模式",为什么一开始不使用XML?解析起来并不难,能够为其强制实施架构是一个很大的优势。

最新更新