各种数据序列化格式进行比较。基本上,是回答以下问题:“能找到比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最接近其前身,因此它可能最接近。