用于数据描述、数据验证和输入验证的 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 很可能留给应用程序生成,而不是让用户作为输入的一部分提供。以下输入未通过验证,因为它缺少架构声明为 requiredid

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 模式的主要内容,如果未能解决你的问题,请参考以下文章

Json Schema 快速入门

通过JSONSchema完成接口自动化测试的数据验证

在 C# 中针对 XSD 模式验证 json 数据

用于验证 json 模式的 jmeter 断言 [关闭]

JSON 模式验证

在 json 模式中验证 2 种可能的数据类型