用于数据描述、数据验证和输入验证的 JSON 模式
Posted
技术标签:
【中文标题】用于数据描述、数据验证和输入验证的 JSON 模式【英文标题】:JSON schema for data description vs data validation vs input validation 【发布时间】:2013-02-09 11:32:50 【问题描述】:在我能找到的关于使用 JSON 架构的内容中,描述有效数据、验证存储数据和验证输入数据的任务似乎存在混淆(或至少缺乏区别)。
一个典型的例子如下:
var schema =
type: 'object',
properties:
id: type: 'integer', required: true ,
name: type: 'string', required: true ,
description: type: 'string', required: false
;
这很适合描述数据存储中的有效数据应该是什么样子,因此也可以验证它(后者并不是非常有用——如果它在存储中它应该已经有效):
var storedData =
id: 123,
name: 'orange',
description: 'delicious'
;
验证输入的效果不是很好。 id
很可能留给应用程序生成,而不是让用户作为输入的一部分提供。以下输入未通过验证,因为它缺少架构声明为 required
的 id
:
var inputData =
name: 'orange',
description: 'delicious'
;
很好, 有人可能会说,架构并不是用来验证直接输入的,只有在应用程序添加了 id
并且数据是用来验证的之后才应该进行验证被存储。
但是,如果架构不是用来验证直接输入,那么 1) javascript 验证器在浏览器中运行的意义,大概是直接输入和 2) 显然是面向输入的readonly
规范中的架构功能?
考虑到可以设置一次但不能更新的属性(如用户名)以及不同的访问级别(例如,橙子的管理员和所有者应该能够更改description
,而对于其他用户,它应该保持readonly
)。
解决此问题的最佳(或至少有效)做法是什么?每个用例都有不同的架构,如下所示?
var baseSchema =
type: 'object',
properties:
id: type: 'integer', required: true ,
name: type: 'string', required: true ,
description: type: 'string', required: false
;
var ownerUpdateSchema =
type: 'object',
properties:
id: type: 'integer', required: false, readonly: true ,
name: type: 'string', required: true ,
description: type: 'string', required: false
;
var userUpdateSchema =
type: 'object',
properties:
id: type: 'integer', required: false, readonly: true ,
name: type: 'string', required: false, readonly: true ,
description: type: 'string', required: false, readonly: true
;
还是别的什么?
【问题讨论】:
【参考方案1】:旁注:“required”现在是 v4 中父元素中的一个数组,而“readOnly”的大写形式不同 - 我将在我的示例中使用这种形式
我同意验证存储的数据非常罕见。如果你只是描述数据,那么你不需要指定“id”是必需的。
要说的另一件事是,这些模式都应该具有可以引用它们的 URI(例如/schemas/baseSchema
)。此时,您可以扩展模式以使其中一些模式需要“id”:
var ownerInputSchema =
type: 'object',
properties:
id: type: 'integer', readOnly: true,
name: type: 'string',
description: type: 'string'
,
required: ['name']
;
var userInputSchema =
allOf: ["$ref": "/schemas/inputSchema"],
properties:
name: readOnly: true
;
var storedSchema =
allOf: ["$ref": "/schemas/inputSchema"],
required: ["id"]
虽然,正如我上面所说,我不确定storedSchema
是否是必要的。你最终得到的是一个描述数据格式的“所有者”模式(作为服务,并且可以由数据所有者编辑),并且你有一个辅助模式,它扩展了它以在附加属性上声明 readOnly
。
【讨论】:
如果您“只是描述数据”,那么指定 id 是必需的非常有用。如果我正在使用您的数据,那么我知道我可以依赖这个字段,否则我需要找到其他东西来用作标识符。【参考方案2】:嗯,我认为 Json-Schema 的目的在 v4 中定义得更清楚。目标是帮助您进行数据结构验证(无论是要被存储、已通过网络发送给您,还是您正在以交互方式创建)。
readOnly 不是 Json-Schema 验证属性,因为它没有验证约束。在 Json-Schema v4 中,只读是超模式定义的一部分。可用于表示不能在 POST 请求中更改该属性。
Json-schema 没有定义您应该如何实现与用户的交互,如果您允许暂时的“坏”数据,或者在您向系统添加更多数据之前必须纠正任何错误。这取决于你。
【讨论】:
以上是关于用于数据描述、数据验证和输入验证的 JSON 模式的主要内容,如果未能解决你的问题,请参考以下文章