时间过得真快, 半年又过去了。
今天得益有空, 正好写篇博文。

数据交换格式

什么是数据交换格式?

通俗一点就是服务器端与客户端之间进行数据传输与交换的格式。

我们遇到的 JSONXML 是最常见的数据交换格式。

<user>
  <id>1</id>
  <name>kraity</name>
</user>
{
  "id": 1,
  "name": "kraity"
}

它们都有各自的优点和缺点, XML 格式臃肿、体积大, JSON 格式清晰、体积小。

可能还有小伙伴说 ProtoBuf, 但是 ProtoBufJSONXML 不配对,
因为 ProtoBuf 需要定义数据结构, 可以算得上是一种协议。

message User {
  int32 id = 1;
  string name = 2;
}

上面定义了一个 Proto, 可以看出没有包含我们塞入的数据。

产品需求

南博是一个写作客户端软件, 那么可能也会用一些数据交换格式,
我们可以发现南博4.0使用了原创一种数据交换格式KAT。

我们都知道, 南博上古版本都是使用一种叫 XML-RPC 框架来完成南博与博客之间的数据交换, 可见使用的是 XML

经过一两年的发展, 我们意识到了解析速度数据大小问题, 不得不寻找另外一种交换格式。
肯定首先想到是 JSON, 南博客户端采用的是 Java 语言原生开发, 那我们首先寻找的就是 JSON 库。

Java 领域里, JSON 库比较出名的有 FastjsonJacksonGson
根据我们已有代码情况切换另外一个库, 经过我们测试筛选, 没有选出完美符合南博当前环境下平滑的切换的JSON库。

然后我们突发奇想, 为什么我们不自己写一个JSON库呢! 于是我们动手就干。 当库写到十分之一时候,
又想到为什么我们一定要选择 JSON 呢, 为什么不原创一种数据交换格式, 设计上对 Java 友好即多类型数据。

于是, 我们参考了 JSONJava。 拟定了一种格式, 至今还是采用当时的设计规则。

User{
  i:id(1)
  s:name(kraity)
}

可能看上去它些许像Java的类, 我们在 JSON 上增加了多类型支持即包名, 包名后面跟随着实例的别名或者变量名。

Useris 我们称这部分为 space
idname 我们称这部分为 alias
1kraity 我们称这部分为 value

花括号 {} 为一个实体 entity, 小括号 () 为一个基本属性 property , 当然实体的属性还可以是实体。

space 对应包名或者类型, alias 对应变量名或者字段, value 自然是 space 的一个实例值。

设计理念

命名上, 我们当时选取 krait 的三个字母KAT, 于是命名这套数据交换格式为KAT

我们在格式上追求清晰、体积小、拓展性强。

规定了基本space的类型映射:

$ -> Object
i -> int
l -> long
f -> float
d -> double
b -> boolean
s -> String
I -> BigInteger
D -> BigDecimal
o -> byte
u -> short
B -> byte[]    // base64

M -> Map       // HashMap
L -> List      // ArrayList
S -> Set       // HashSet
A -> Array     // Object[]

space 可以根据使用者自己而定, 比如自定义日期类型 Date:modified(Mon Feb 22 00:00:00 GMT 2022)。还可以将上面规定的转为其他类型映射。

在实践项目开发中, space 可以是包名例如 plus.kat.entity.User, 找到这个类的解释器然后自定义解析。

小伙伴可能会说, 怎么会记得住这多space对应关系, 当然我们支持通配符 $, 当时它仅能表示几种类型, 但是如果使用者绑定了实体Class那么根据字段类型而解析。

User{
  $:id(1)
  $:name(kraity)
  $:role()
  $:blocked(false)
}

或者再简单一点

User{
  :id(1)
  :name(kraity)
  :role()
  :blocked(false)
}

解析机制

KAT库反序列化时采用管道方式。 解析器 Codec 拟雷达 Radar 扫描方式将解析的数据一层一层的通过 Pipeline 传输到 Parser, Parser 则根据 space 进行寻找类型解释器然后解析 value, 如果没有解析器那么丢弃这个实体或者属性, 继续解析后面的。

KAT经过一年的发展, 最近支持了注释。

# this is a test entity
User{
    l:uid(1)
    s:name(kraity)
    s:role(developer)

    # status
    b:blocked(0)

    # extra data
    M:contact{
        I:age(6)
        D:devote(1024)
    }
}

最后, KAT库我们命名为KAT+, 同时注册了域名 kat.plus, KAT+ 不仅支持解析 KAT 还支持解析 JSON (KAT库是通用的, 只需实现 JSONCodec 即可嵌入)。

开源共享

我们预计将在今年八月份开源KAT+, 以及完善更多的流行框架适配。

KAT+ Team Github

我们会开源在这个组织仓库里, 开源协议 Apache-2.0。

#none
更新于: 2022年06月28日 16:19
634
4
发表评论