数据描述与数据验证与输入验证的JSON模式 [英] JSON schema for data description vs data validation vs input validation

查看:107
本文介绍了数据描述与数据验证与输入验证的JSON模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用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 }
    }
};

还有别的吗?

解决方案

侧注:"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.

In what I can find about using JSON schema, there seems to be a confusing conflation of (or at least a lack of distinction among) the tasks of describing valid data, validating stored data, and validating input data.

A typical example looks like:

var schema = {
    type: 'object',
    properties: {
        id: { type: 'integer', required: true },
        name: { type: 'string', required: true },
        description: { type: 'string', required: false }
    }
};

This works well for describing what valid data in a data store should look like, and therefore for validating it (the latter isn't terribly useful—if it's in a store it should be valid already):

var storedData = {
    id: 123,
    name: 'orange',
    description: 'delicious'
};

It doesn't work that well for validating input. id is most likely left for the application to generate and not for the user to provide as part of the input. The following input fails validation because it lacks the id which the schema declares to be required:

var inputData = {
    name: 'orange',
    description: 'delicious'
};

Fine, one might say, the schema isn't meant to validate direct input, validation should only occur after the application added an id and the data is what is meant to be stored.

If the schema isn't meant to validate direct input, however, what is 1) the point of JavaScript validators running in the browser, presumably being fed direct input and 2) the point of the obviously input-oriented readonly schema feature in the spec?

Ground gets shakier when thinking of properties that can be set once but not updated (like a username), as well as different access levels (e.g. the admin and the owner of the orange should be able to change the description, while for other users it should stay readonly).

What is the best (or at least working) practice to deal with this? A different schema for each use case, like below?

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 }
    }
};

Or something else?

解决方案

Side-note: "required" is now an array in the parent element in v4, and "readOnly" is capitalised differently - I'll be using that form for my examples

I agree that validating the stored data is pretty rare. And if you're just describing the data, then you don't need to specify that "id" is required.

Another thing to say is that these schemas should all have URIs at which they can be referenced (e.g. /schemas/baseSchema). At that point, you can extend the schemas to make "id" required in some of them:

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"]
}

Although, as I said above, I'm not sure storedSchema should be necessary. What you end up with is one "owner" schema that describes the data format (as served, and as editable by the data owner), and you have a secondary schema that extends that to declare readOnly on an additional property.

这篇关于数据描述与数据验证与输入验证的JSON模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆