数据验证

数据验证是开箱即用的。您的配置包括API管理的每个资源的模式定义。发送到要插入/更新的API的数据将根据架构进行验证,并且只有验证通过时才会更新资源。

$ curl -d '[{"firstname": "bill", "lastname": "clinton"}, {"firstname": "mitt", "lastname": "romney"}]' -H 'Content-Type: application/json' http://myapi/people
HTTP/1.1 201 OK

响应将包含请求中提供的每个项目的成功/错误状态:

{
    "_status": "ERR",
    "_error": "Some documents contains errors",
    "_items": [
        {
            "_status": "ERR",
            "_issues": {"lastname": "value 'clinton' not unique"}
        },
        {
            "_status": "OK",
        }
    ]
]

在上面的示例中,第一个文档没有验证,因此整个请求被拒绝。

当所有文档通过验证并正确插入时,响应状态为 201 Created .如果任何文档未通过验证,则响应状态为 422 Unprocessable Entity 或由定义的任何其他错误代码 VALIDATION_ERROR_STATUS 配置。

有关如何定义文档架构和标准验证规则的信息,请参阅 架构定义 .

扩展数据验证

数据验证基于 Cerberus 验证系统,因此是可扩展的。事实上,EVE的MongoDB数据层本身扩展了Cerberus验证,实现了 uniquedata_relation 约束条件, ObjectId 数据类型和 decimal128 在标准规则之上。

自定义验证规则

假设在您特定且非常特殊的用例中,某个值只能表示为奇数。您决定添加对新的 isodd 验证模式的规则。这就是您将如何实现这一点:

from eve.io.mongo import Validator

class MyValidator(Validator):
    def _validate_isodd(self, isodd, field, value):
        if isodd and not bool(value & 1):
            self._error(field, "Value must be an odd number")

app = Eve(validator=MyValidator)

if __name__ == '__main__':
    app.run()

通过对基础mongo验证器类进行子类化,然后添加自定义 _validate_<rulename> 方法,您扩展了 架构定义 语法和新的自定义规则 isodd 在您的架构中可用。现在您可以执行以下操作:

'schema': {
    'oddity': {
        'isodd': True,
        'type': 'integer'
      }
}

Cerberus 和 Eve 也提供 function-based validationtype coercion 基于类的自定义验证的轻量级替代方案。

自定义数据类型

您也可以通过简单地添加 _validate_type_<typename> 子类的方法。考虑一下EVE源代码中的以下代码片段。

def _validate_type_objectid(self, value):
    """ Enables validation for `objectid` schema attribute.

    :param value: field value.
    """
    if isinstance(value, ObjectId):
        return True

此方法支持MongoDB ObjectId 输入您的模式,允许如下操作:

'schema': {
    'owner': {
        'type': 'objectid',
        'required': True,
    },
}

您也可以检查 source code 对于EVE自定义验证,您将发现更高级的用例,例如 uniquedata_relation 约束条件。

有关更多信息

备注

我们只触及了数据验证的表面。请务必检查 Cerberus 有关可用验证规则和数据类型的完整列表的文档。

还请注意,Cerberus要求固定在0.9.2版上,该版本仍然支持 validate_update 方法用于 PATCH 请求。已为EVE版本0.8计划升级到cerberus 1.0+。

允许未知

通常情况下,您不希望客户机在文档中插入未知字段。然而,在某些情况下,这是可取的。例如,在开发周期中,或者在处理非常异构的数据时。毕竟,不强制规范化信息是MongoDB和许多其他NoSQL数据存储的卖点之一。

在EVE中,通过设置 ALLOW_UNKNOWN 选择权 True .启用此选项后,匹配架构的字段将正常验证,而未知字段将被安静地存储,不会出现故障。您还可以通过设置 allow_unknown 本地选项。

考虑以下域:

DOMAIN: {
    'people': {
        'allow_unknown': True,
        'schema': {
            'firstname': {'type': 'string'},
            }
        }
    }

通常只能添加(post)或编辑(patch) firstnames/people 终结点。然而,自从 allow_unknown 已启用,即使这样的有效负载也将被接受:

$ curl -d '[{"firstname": "bill", "lastname": "clinton"}, {"firstname": "bill", "age":70}]' -H 'Content-Type: application/json' http://myapi/people
HTTP/1.1 201 OK

请注意

使用此功能时要格外小心。还要注意,当启用此选项时,客户端实际上能够 adding 通过补丁的字段(编辑)。

ALLOW_UNKNOWN 对于只读API或需要返回整个文档的端点也很有用,如基础数据库中所示。在这个场景中,您不想费心验证模式。整个API刚刚设置 ALLOW_UNKNOWNTrue 然后 schema: {{}} 在每个端点。对于单个端点,请使用 allow_unknown: True 相反。

架构验证

默认情况下,模式经过验证,以确保它们符合 架构定义 .

为了处理不一致的模式,添加 自定义验证规则 用于模式中使用的不一致键。