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