有比JSON更好的东西吗?

2020-10-28 11:11:03 浏览数 (1)

各种数据序列化格式进行比较。基本上,是回答以下问题:“能找到比JSON更好的东西吗?”。 这里找的是用于数据序列化的语言,而不是配置文件。

有两个轴线来比较各种语言:

  • 自描述与模式定义的格式
  • 可读格式与机器可读格式

即,是否在接收程序检查的单独文件(架构)中定义了结构的类型信息,或者消息本身是否包含类型信息。这有点类似于静态和动态类型的编程语言之间的差异。像编程语言一样,两者都有优点和缺点,但两者都不总是比对方好。这里不会真正比较工具的高低。目的是查看格式的内在特性。

不要与RPC协议混淆,尽管其中许多东西都在RPC协议中使用。无论是否以这种方式实现,HTTP / REST接口通常只是一种RPC协议。


人类可读的语言

JSON格式

http://json.org/

我们都知道JSON,都同意它足够好。

类别:易于理解,自我描述。尽管用于RPC协议的描述词汇表存在(https://json-schema.org/),但是似乎很少使用。

用户:每个人

优点:

  • 与主要的编程语言相似–易于理解和调试
  • 简单–易于阅读,编写和理解。

缺点:

  • 类型很少-没有日期/时间,没有实数,没有结构体,没有联合/元组/等
  • 没有规范化的形式,字段可能会重新排序,重复等。这使hash变得困难,必须阅读整个消息才能开始对其进行验证,等等。
  • 没有好的方法来包含二进制数据

YAML

https://yaml.org/

最初是XML的一种更简单的替代品。

类别:易于理解,自我描述。

用户:很多人

优点:

  • 基本形式的阅读和写作非常简单
  • 视觉上简洁

缺点:

  • 太复杂了–为JSON的严格超集,并且没有人使用该形式
  • 多种语言实现彼此不同

XML格式

https://zh.wikipedia.org/wiki/XML

W3C的标准。

类别:人类可读的,具有常见模式用法的自我描述。具有RPC协议和许多其他复杂的东西。

用户:每个无法避免的人。

优点:

  • 用于配置架构和验证
  • 简单易用
  • 实际上对于写文档来说还不错

缺点:

  • 一切都是字符串输入
  • 没有实际的数组
  • 复杂化,很冗长
  • 大概有3-4种不同的方式来完成每一件事
  • 仍然不是包含二进制数据的好方法

机器可读语言

protocol-buffers

https://developers.google.com/protocol-buffers/

a.k.a协议buffer,但这是一个很别扭的名字。Google的常用快速在线序列化格式。

类别:机器可读的,模式定义的。有围绕它构建的RPC协议。

用户: Google,基本上每个人

优点:

  • 在Google的支持下,它将很好地发挥Google的价值
  • 基本上合理不错
  • 现在对版本控制架构提供了一些支持

缺点:

  • 在Google的支持下,它将很好地发挥Google的价值
  • 不是特别简单
  • 可能还有改进的空间
  • 它的类型系统可能会更好

Cap'n Proto

https://capnproto.org/

其他二进制序列化协议。

类别:机器可读的,模式定义的。主要是为RPC设计的。

用户: sandstorm.io,Cloudflare ?其他各种人,但似乎人数不多

优点:

  • 设计快
  • 由Google致力于Protobuf的人之一制作,因此背后有很多经验。就是说,这并不意味着这永远都是对的,但肯定有试图表达的观点。
  • 精致的RPC是标准包的一部分
  • 专为零拷贝反序列化而设计
  • 专为架构而设计
  • 可爱的名字
  • 非常明确地说明正确性和一致性,例如字段排序和布局

缺点:

  • 非常明确地说明正确性和一致性,例如字段排序和布局
  • 许多文档和概念都很底层,你通常不需要它
  • 似乎比protobuf更复杂-这可能是第三方实现较少的原因之一

thrift

https://thrift.apache.org/

Apache的Protobuf版本。有人实际使用吗?显然,Facebook是因为他们发明了它,然后将其提供给了Apache。还有谁?

类别:机器可读的,模式定义的。主要为RPC设计。

用户:基本上主要是Facebook?Twitter和AirBNB显然也使用它,也不是不受欢迎。

优点:

  • 有用?

缺点:

  • 文档很烂
  • Apache的​开源项目的悲剧
  • 显然仍然不如flatbuffers

flatbuffers

https://google.github.io/flatbuffers/

感觉有点像Google的Cap'n Proto,因为它具有一些相同的设计目标-零副本序列化和布局更适合版本控制。

类别:机器可读的,模式定义的。包括RPC协议。

用户: Google,Cocos2D,Facebook的移动客户端

优点:

  • 专为零拷贝反序列化而设计
  • 专为架构而设计

缺点:

  • 相同问题已经由Capnp解决
  • 出于某种原因包括JSON解析器?
  • 类型系统对于实际应用来说有点贫乏

CBOR

https://cbor.io/

基本上是对JSON的二进制重新构想。

类别:机器可读的,自我描述的。

用户: ???

优点:

  • 相当不错的类型系统–诸如fixnum,datetime,blob等
  • 紧凑
  • 内置可扩展性
  • 旨在替代JSON
  • IETF标准

缺点:

  • 尽管出于紧凑性和综合类型的考虑,但它比它需要的复杂得多。例如,在可能的情况下,将数字密集地打包为更少的位。
  • 出于某种原因,实际上似乎没有被广泛采用吗?

msgpack

https://msgpack.org/

CBOR是从msgpack派生的。设计简单紧凑。

类别:机器可读的,自我描述的。

用户: Redis,还有其他几个吗?

优点:

  • 简单
  • 紧凑

缺点:

  • 规格有点弱
  • 没有真正的元组或枚举类型
  • 为什么不只是CBOR?

BSON

http://bsonspec.org/

顾名思义,JSON的二进制形式。由MongoDB创建为其内部数据格式。

类别:机器可读的,自我描述的。

用户: MongoDB

优点:

  • 类型系统充满了MongoDB特定的类型,但是相当实用

缺点:

  • 类型系统相当实用,但是充满了不赞成使用的,以及MongoDB特定的东西
  • C字符串–尽管也有随机的非C字符串。
  • 它的数组是反对序列化的怪胎
  • 基本上是MongoDB的实现细节,看起来像这样

其他

有趣但实际上不在序列化语言范围之内的语言。

toml

https://github.com/toml-lang/toml

它被设计为配置语言,而不是序列化格式。从根本上讲,这是一种使像Windows .INI文件那样简单和普遍存在的尝试,而这实际上是一种规范,而不是一种流行语言。

类别:易于理解的分类,虽然通常要尝试使用特定的数据结构,但它还是可以自我描述的。

用户:各种,尤其是cargo(Rust的构建工具)

优点:

  • 在没有深度嵌套结构的情况下,可以很好地用作配置语言

缺点:

  • 尝试制作深度嵌套的结构时效果不佳

ron

https://github.com/ron-rs/ron

Rust的对象符号。因为将Rust的ML-y类型系统导入JSON并不是一件很有趣的事情。为此目的,其效果惊人,但基本上在其他地方都没有尝试过。

类别:易于理解的分类,虽然通常要尝试使用特定的数据结构,但它还是可以自我描述的。

用户:少数,尤其是Amethyst.rs

优点:

  • 适用于复杂的功能样式语言的良好类型系统
  • 简单合理紧凑
  • 实际上非常擅长

缺点:

  • 年轻,规格不足,以Rust为中心

bincode

https://github.com/servo/bincode

主要包括完整性。它不是在不能保证稳定性的单个特定实现之外进行标准化的,因此不适用于通用用途。它旨在用作Servo的快速简便的RPC / IPC格式,而实际格式基本上是该目标的实现细节。

用户:服务器,是由内向的人编写的程序,他们并不关心彼此之间的交谈。

优点:

  • 紧凑,快速,简单。
  • 具有Rust代码的IPC基本透明地工作。

缺点:

  • 除了该特定库的特定版本以外,没有其他定义。

ASN.1

https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One

一些愚蠢的电信标准组织试图做protobuf以后会做的事情。问题的标准机构与创造了一种故意的现实幻觉的机构-OSI网络模型有关。

类别:机器可读的,模式定义的。

用户:LDAP和SSL证书。

优点:

  • 强大而精确的字体系统
  • 到处都有模式
  • 二进制和文本形式,以及将其转换为几乎任何其他数据格式的方法

缺点:

  • 大约有十亿种数据变体格式
  • 超级冗长
  • 实际使用起来太复杂了,更不用说实现了

XDR

https://tools.ietf.org/html/rfc4506

Sun Microsystems尝试做protobuf以后会做的事情。

基本上,一个非常出色的C编码器并想要通过网络传输结构化数据时,会想到的事情。

类别:机器可读的,模式定义的。

用户:仍在某些地方使用,例如ZFS,NFS等

优点:

  • 相当不错

缺点:

  • 除非您是1990年代初的C程序,否则不一定做得太多

S-Expressions

Lisp代码是由什么组成的,是从更文明的时代开始的一种优雅的表示法。像许多Lisp解决方案一样,它非常有效,直到需要使两个Lisp实现使用同一类东西为止。至少从1970年代开始,就一直没有尝试过在Lisp之外流行。

没有实际的通用规范,更不用说实现了。EDN是一个不错的开始。

类别:易于理解,自我描述

用户:任何类似Lisp的语言,主要的“实际例子”是Scheme,Racket,Clojure和理论上常见的Lisp。

优点:

  • 轻快的人会喜欢它,非轻快的人会讨厌它。
  • 合理简单好看

缺点:

  • 轻快的人会喜欢它,非轻快的人会讨厌它。
  • 对于列表以外的复合数据类型,实际上没有公认的语法。
  • READ尽管已经被证明是一个糟糕的主意,但任何使用Lisp解释器的人都会尝试使用它进行阅读。
  • 无论您使用哪种形式的S表达式,都会在某处使人烦恼,因为他们特定的Lisp形式无法使用加载它READ。
  • 人们将尝试在其中编写Lisp代码。

结论

够好了:

  • JSON?
  • Protobuffer
  • Cap'n Proto
  • Flatbuffers
  • CBOR
  • msgpack

避免:

  • YAML
  • XML格式
  • Thrift?
  • BSON

XML的变革

这实际上是一个有趣的原因,因为很容易跟踪每种格式,ASN.1,XDR和都早于当前的互联网时代。现代始于XML。XML有很长的一段历史,但是却形成了一个瓶颈。人们实际上关心的大多数事物都是对XML的响应,因此这就是开始的地方。最广泛使用的事物的家谱将是:


JSON的替代品

因此,当实际查看此列表时,实际上并没有JSON的替代品。没有比“人类可读”列更好的了。哦,有很多尝试过的方法,例如:

  • JSON5(https://json5.org/)
  • STOB(http://igagis.github.io/stob/)
  • ENO(https://eno-lang.org/)
  • AXON(https://intellimath.bitbucket.io/axon/)
  • BRE(https://baremessages.org/)

…但是这些几乎没有更新最新版本,更不用说广泛使用了。由于JSON5最接近其前身,因此它可能最接近。

0 人点赞