通用的校验器,可传递一个自定义的块。注意,如果校验不通过,需要主动地抛出 Meta::JsonSchema::ValidationError. 例如:
property :mobile, validate: lambda do |value|
raise Meta::JsonSchema::ValidationError, '手机号格式不正确' unless value =~ /\d+/
end有关必须要传递的字段可通过 required: true 设置。
property :name, required: true # 必须
property :age, required: false # 非必须对于字符串属性,即使是空白字符串也无法通过 required 校验。这时可通过设置 allow_empty: true 来改变这一行为。
property :name, required: { allow_empty: true }数组属性默认是允许空数组的。如果你不喜欢这种行为,需明确设置 allow_empty 为 false.
format 校验可传递一个正则表达式选项,参数需匹配正则表达式代表的模式。
property :date, format: /^\d{4}-\d{2}-\d{2}$/对于枚举值来说,通过 allowable 来定义可选项。
property :gender, allowable: ['male', 'female']如果用户传递了不同于 male 或 female 的值,就会报错。
框架中使用 rescue_error 捕获异常,框架能够抛出的异常包括:
Meta::Errors::NoMatchingRoute:路由不匹配时。Meta::Errors::ParameterInvalid:参数存在异常时。Meta::Errors::RenderingInvalid:响应值存在异常时。Meta::Errors::UnsupportedContentType:框架只支持application/json的参数格式。当客户端的请求体不是这个格式时,会抛出这个错误。
框架默认提供的语言是 zh-CN,可通过文件 config/locales/zh-CN.yml 查看可配置的内容。如果需要添加其他语言的支持,需要自行配置。
locked 方法返回一个新的实体,它将若干选项锁定。例如,锁定某个实体为 scope: 'full':
# 如下定义一个 Entity
class ArticleEntity < Meta::Entity
property :title, type: 'string'
property :content, type: 'string', scope: 'full'
property :hidden, type: 'boolean', scope: 'o'
end
# 在 using 时锁定 scope
params do
property :article, using: ArticleEntity.locked(scope: 'full')
end如上,article 内容仅包含字段 title、content.
再例如,我们也可以去掉某些指定的字段,这时用到 exclude: ... 选项。下面的例子将达到与上面例子等效的结果:
# 在 using 时去掉某些字段
params do
property :article, using: ArticleEntity.locked(exclude: [:hidden])
end注意 exclude 的传递格式,它接受一个数组,并且字段应用符号而不是字符串。
最后一个示例是如何处理缺失字段的。在处理请求参数时,我们有时候需要包括缺失字段,有时候需要去掉缺失字段。默认情况下是按照前者处理的,如果需要按照后者的方式处理,需要锁定选项 discard_missing: true:
# 在 using 时不包括缺失字段
params do
property :article, using: ArticleEntity.locked(discard_missing: true)
end我们也可以综合这几个选项(由于综合 scope 和 exclude 往往没有意义,这里我们只综合 scope 和 discard_missing):
params do
property :article, using: ArticleEntity.locked(scope: ['full'], discard_missing: true)
end如上,scope 选项也可以传递数组的。
除了 locked 方法,还包括几个便捷方法。例如 lock 方法,它与 locked 在某种程度上等价:
ArticleEntity.lock(:scope, 'full') # 它与 locked(scope: 'full') 等价
ArticleEntity.lock(:discard_missing, true) # 它与 locked(discard_missing: true) 等价还有 lock_xxx 便捷方法:
ArticleEntity.lock_scope('full') # 它与 locked(scope: 'full') 等价在 Open API 中,参数和请求体是分开定义的,它们不属于同一个语义。下面是一个 HTTP 请求的示例:
POST /request?foo=foo
X-Bar: bar
{
"user": ...
}其中 foo=foo 和 X-Bar: bar 是参数,而 JSON 格式的 { "user": ... } 才是请求体。
在 Meta 框架中,为了方便,可以用同一个宏命令(即 params)来定义参数和请求体:
params do
param :foo, in: 'query'
param 'X-Bar', in: 'header'
param :user, type: 'object'
end而事实上,Meta 框架也给出了分开定义参数和请求体的的宏命令。也许有些混淆,parameters 宏专用于定义参数,request_body 宏用于定义请求体:
parameters do
param :foo, in: 'query'
param 'X-Bar', in: 'header'
end
request_body do
property :user, type: 'object'
end而在应用中,也许有些混淆,params、parameters、request_body 能够获取到参数和请求体:
action do
params # 合并获取参数和请求体
parameters # 专用于获取参数
request_body # 专用于获取请求体
end面对这两种使用方式,有何使用上的建议呢?我的建议是,你习惯用哪种就用哪种。
规定是否忽略缺失的属性。所谓缺失的属性,是指在 ObjectSchema 实体宏中定义,但数据中不包含这个键值的属性。你可以将 discard_missing: true 视为 HTTP Patch 方法,discard_missing: false 视为 HTTP Put 方法。
规定多余的属性的处理办法。所谓多余的属性,是指未在 ObjectSchema 实体宏中定义,但数据中依然存在这个键值的属性。一般来讲我们允许前端传递一些多余的属性,但可能在内部测试时设定为更严格的条件。