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

我通常在 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 本身的属性,但这对于传达版本更改时客户端应该预期的更改类型很有用。

https://stackoverflow.com/questions/10042742/

相关文章:

jquery - getJSON 到 console.log() 输出 json 结构

javascript - 在输入隐藏字段中存储返回 json 值

java - 如何使用 @ResponseBody 从 Spring Controller 返回 J

java - 确定 JSON 提要中是否存在值的更好方法

javascript - 将 JSON 字符串转换为 Javascript 数组

ruby-on-rails - 设计 API 身份验证

java - 在 JSON 对象中解析 JSON 数组

php - 为什么 json_encode 添加反斜杠?

jquery - 使用 Highcharts 通过 JSON 重新加载图表数据

java - Gson:@Expose 与 @SerializedName