如何判断 JSON 模式与 Java 中的另一个模式兼容?
How to tell a JSON schema is compatible with another in Java?
例如,我有一个 JSON 架构如下所示:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": { "$ref": "#/definitions/address" }
}
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
}
This schema表示一个对象有两个变量billing_address和shipping_address,它们都是输入 address,其中包含三个属性:street_address、city 和 状态.
现在我得到了另一个 "larger" 模式:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": { "$ref": "#/definitions/address" },
"new_address": { "$ref": "#/definitions/address" }
}
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" },
"zip_code": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
}
如您所见,我在架构中添加了一个新的 属性 new_address,并在 address 有一个名为 zip_code 的新 属性,它 不是必需的 属性。
因此,如果我从旧的 JSON 模式创建了一个对象,它也应该可用于新的 JSON 模式。在这种情况下,我们将称新模式与旧模式兼容。 (换句话说,新模式是旧模式的扩展,但没有修改。)
问题是在 Java 中如何判断一个模式是否与另一个模式兼容?复杂的情况也应注意,例如 "minimum" 属性 用于数字字段。
测试一下。在我当前的项目中,我正在编写以下合同测试:
1) 具有 Java 域对象,我将其序列化为 JSON 并将其与参考 JSON 数据进行比较。我使用 https://github.com/skyscreamer/JSONassert 来比较两个 JSON 字符串。
参考JSON数据,需要使用'smaller schema'对象。
2) 有了样本 JSON 数据,我将其反序列化为我的域对象,并验证反序列化是否成功。我将反序列化结果与模型对象进行比较。对于示例 JSON 数据,您应该使用 'larger schema' 对象。
此测试验证 'larger schema' JSON 数据是否向后兼容您的 'smaller schema' 域。
我在领域模型的每一层都编写了这些测试——一个用于顶级对象,另一个用于每个重要的嵌套对象。这需要更多的测试代码和更多的 JSON 示例数据,但会提供更好的信心。如果出现故障,将对错误消息进行微调,您将确切地知道层次结构的级别被破坏(JSON断言错误消息可能有很多错误,并且对于深层嵌套的对象层次结构来说阅读起来并不简单)。所以这是一个权衡
* 维护测试代码和数据的时间
* 错误消息的质量
这样的测试很快 - 他们只需要 JSON serialization/deserialization.
https://github.com/spring-cloud/spring-cloud-contract 将帮助您为 REST API、消息传递等编写合同测试-但对于简单的情况,我上面给出的程序可能就足够了
例如,我有一个 JSON 架构如下所示:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": { "$ref": "#/definitions/address" }
}
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
}
This schema表示一个对象有两个变量billing_address和shipping_address,它们都是输入 address,其中包含三个属性:street_address、city 和 状态.
现在我得到了另一个 "larger" 模式:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": { "$ref": "#/definitions/address" },
"new_address": { "$ref": "#/definitions/address" }
}
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" },
"zip_code": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
}
如您所见,我在架构中添加了一个新的 属性 new_address,并在 address 有一个名为 zip_code 的新 属性,它 不是必需的 属性。
因此,如果我从旧的 JSON 模式创建了一个对象,它也应该可用于新的 JSON 模式。在这种情况下,我们将称新模式与旧模式兼容。 (换句话说,新模式是旧模式的扩展,但没有修改。)
问题是在 Java 中如何判断一个模式是否与另一个模式兼容?复杂的情况也应注意,例如 "minimum" 属性 用于数字字段。
测试一下。在我当前的项目中,我正在编写以下合同测试:
1) 具有 Java 域对象,我将其序列化为 JSON 并将其与参考 JSON 数据进行比较。我使用 https://github.com/skyscreamer/JSONassert 来比较两个 JSON 字符串。 参考JSON数据,需要使用'smaller schema'对象。
2) 有了样本 JSON 数据,我将其反序列化为我的域对象,并验证反序列化是否成功。我将反序列化结果与模型对象进行比较。对于示例 JSON 数据,您应该使用 'larger schema' 对象。 此测试验证 'larger schema' JSON 数据是否向后兼容您的 'smaller schema' 域。
我在领域模型的每一层都编写了这些测试——一个用于顶级对象,另一个用于每个重要的嵌套对象。这需要更多的测试代码和更多的 JSON 示例数据,但会提供更好的信心。如果出现故障,将对错误消息进行微调,您将确切地知道层次结构的级别被破坏(JSON断言错误消息可能有很多错误,并且对于深层嵌套的对象层次结构来说阅读起来并不简单)。所以这是一个权衡 * 维护测试代码和数据的时间 * 错误消息的质量
这样的测试很快 - 他们只需要 JSON serialization/deserialization.
https://github.com/spring-cloud/spring-cloud-contract 将帮助您为 REST API、消息传递等编写合同测试-但对于简单的情况,我上面给出的程序可能就足够了