json - 使用 JSON 协议(protocol)处理版本控制的最佳方法是什么?

标签 json serialization binary versioning

我通常在 C# 中编写代码的所有部分,并且在编写序列化协议(protocol)时,我使用 FastSerializer 快速高效地序列化/反序列化类。它也很容易使用,并且相当直接地进行“版本控制”,即处理不同版本的序列化。我通常使用的东西是这样的:

public override void DeserializeOwnedData(SerializationReader reader, object context)
{
    base.DeserializeOwnedData(reader, context);
    byte serializeVersion = reader.ReadByte(); // used to keep what version we are using

    this.CustomerNumber = reader.ReadString();
    this.HomeAddress = reader.ReadString();
    this.ZipCode = reader.ReadString();
    this.HomeCity = reader.ReadString();
    if (serializeVersion > 0)
        this.HomeAddressObj = reader.ReadUInt32();
    if (serializeVersion > 1)
        this.County = reader.ReadString();
    if (serializeVersion > 2)
        this.Muni = reader.ReadString();
    if (serializeVersion > 3)
        this._AvailableCustomers = reader.ReadList<uint>();
}

public override void SerializeOwnedData(SerializationWriter writer, object context)
{            
    base.SerializeOwnedData(writer, context);
    byte serializeVersion = 4; 
    writer.Write(serializeVersion);


    writer.Write(CustomerNumber);
    writer.Write(PopulationRegistryNumber);            
    writer.Write(HomeAddress);
    writer.Write(ZipCode);
    writer.Write(HomeCity);
    if (CustomerCards == null)
        CustomerCards = new List<uint>();            
    writer.Write(CustomerCards);
    writer.Write(HomeAddressObj);

    writer.Write(County);

    // v 2
    writer.Write(Muni);

    // v 4
    if (_AvailableCustomers == null)
        _AvailableCustomers = new List<uint>();
    writer.Write(_AvailableCustomers);
}

所以很容易添加新东西,或者如果选择完全改变序列化。

但是,我现在想使用 JSON 的原因与此处无关 =) 我目前正在使用 DataContractJsonSerializer,我现在正在寻找一种方法来获得与上面使用 FastSerializer 相同的灵 active .

所以问题是;创建 JSON 协议(protocol)/序列化并能够如上所述详细说明序列化的最佳方法是什么,这样我就不会因为另一台机器尚未更新其版本而中断序列化?

最佳答案

对 JSON 进行版本控制的关键是始终添加新属性,而不是删除或重命名现有属性。这类似于 how protocol buffers handle versioning .

例如,如果您从以下 JSON 开始:

{
  "version": "1.0",
  "foo": true
}

并且您想将 "foo" 属性重命名为 "bar",不要只是重命名它。相反,添加一个新属性:

{
  "version": "1.1",
  "foo": true,
  "bar": true
}

由于您永远不会删除属性,因此基于旧版本的客户端将继续工作。这种方法的缺点是 JSON 会随着时间的推移而变得臃肿,您必须继续维护旧属性。

向客户明确定义“边缘”案例也很重要。假设您有一个名为 "fooList" 的数组属性。 "fooList" 属性可以采用以下可能的值: 不存在/未定义(该属性实际上不存在于 JSON 对象中,或者它存在并设置为 "undefined")、null、空列表或具有一个或多个值的列表。让客户了解行为方式非常重要,尤其是在未定义/空/空的情况下。

我还建议阅读 semantic versioning作品。如果您在版本号中引入语义版本控制方案,则可以在次要版本边界上进行向后兼容的更改,而可以在主要版本边界上进行重大更改(客户端和服务器都必须就相同的主要版本达成一致)。虽然这不是 JSON 本身的属性,但这对于传达版本更改时客户端应该预期的更改类型很有用。

关于json - 使用 JSON 协议(protocol)处理版本控制的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10042742/

相关文章:

javascript - 不确定如何处理 javascript 并在此特定实例中进行 Mechanize

json - 如何在 Go json marshal 中显示空对象而不是空结构或 nil

javascript - 如何序列化 JavaScript 中的函数?

php - 读取文件的二进制代码...在 PHP 中

c - 如何使用位移位/掩码将二进制转换为十六进制

java - java中十进制数字的8位表示

javascript - 如何使用 Python 将缩进的 .yaml 文件转换为 json?

java - Spring MVC -> JSON 响应

java - 尝试序列化 JTS 点 - 此方法不支持 GeometryCollection 参数

java - 读取序列化文件 - java