New release is coming soon! If you want to try out the latest features, simply run
npm i -s moleculer@next
. The docs for the latest version are available
here.
参数验证
验证中间件用于 Actions 和Events 参数验证。
Fastest Validator 默认情况下,Moleculer 使用 fastest-validator 库。
Default usage
module .exports = { nodeID: "node-100" , validator: true }
按名称设置验证器
module .exports = { nodeID: "node-100" , validator: "Fastest" }
带选项的示例
module .exports = { nodeID: "node-100" , validator: { type: "Fastest" , options: { useNewCustomCheckerFunction: true , defaults: { }, messages: { }, aliases: { } } } }
动作验证 为了执行参数校验,您需要在动作中定义 params
属性,并为动作传入 ctx.params
以创建验证模式。
示例
const { ServiceBroker } = require ("moleculer" );const broker = new ServiceBroker({ validator: true }); broker.createService({ name: "say" , actions: { hello: { params: { name: { type : "string" , min : 2 } }, handler(ctx) { return "Hello " + ctx.params.name; } } } }); broker.call("say.hello" ).then(console .log) .catch(err => console .error(err.message)); broker.call("say.hello" , { name : 123 }).then(console .log) .catch(err => console .error(err.message)); broker.call("say.hello" , { name : "Walter" }).then(console .log) .catch(err => console .error(err.message));
在 Runkit 运行
验证模式示例
{ id: { type : "number" , positive : true , integer : true }, name: { type : "string" , min : 3 , max : 255 }, status: "boolean" }
Documentation 在库文档 中查找更多关于验证模型的信息
异步自定义验证器 (Async custom validator) FastestValidator(>= v1.11.0
)支持自定义异步验证器,这意味着您可以为自定义验证器函数传递元数据(Metadata) 。 在Moleculer里,FastestValidator将ctx
作为元数据(Metadata)传递。 这意味着您可以访问当前上下文(Context)、服务(service)、中介(broker)。 这允许您在自定义检查器函数中进行异步调用(例如调用另一个服务)。 要启用它,您必须在moleculer.config.js
中将useNewCustomCheckerFunction
设置为true
。
启用自定义异步验证
module .exports = { validator: { type: "FastestValidator" , options: { useNewCustomCheckerFunction: true , defaults: { }, messages: { }, aliases: { } } } }
使用自定义异步验证
module .exports = { name: "posts" , actions: { params: { $$async : true , owner: { type : "string" , custom : async (value, errors, schema, name, parent, context) => { const ctx = context.meta; const res = await ctx.call("users.isValid" , { id : value }); if (res !== true ) errors.push({ type : "invalidOwner" , field : "owner" , actual : value }); return value; } }, }, } }
事件验证 也支持事件参数验证。 要启用它,在事件中定义 params
。
注意,同时有动作错误发生时,验证错误不会回送给调用者。 事件验证错误会输出到日志,您也可以使用 global error handler 来捕获它们。
module .exports = { name: "mailer" , events: { "send.mail" : { params: { from : "string|optional" , to: "email" , subject: "string" }, handler(ctx) { this .logger.info("Event received, parameters OK!" , ctx.params); } } } };
自定义验证器 您也可以实现自定义验证器。 推荐直接复制 Fastest Validator 代码,并实现 compile
和 validate
方法。
创建自定义验证器
const BaseValidator = require ("moleculer" ).Validators.Base;class MyValidator extends BaseValidator {}module .exports = { nodeID: "node-100" , validator: new MyValidator() }
生成 Joi 验证器
const { ServiceBroker } = require ("moleculer" );const BaseValidator = require ("moleculer" ).Validators.Base;const { ValidationError } = require ("moleculer" ).Errors;const Joi = require ("joi" );class JoiValidator extends BaseValidator { constructor () { super (); } compile(schema) { return (params ) => this .validate(params, schema); } validate(params, schema) { const res = schema.validate(params); if (res.error) throw new ValidationError(res.error.message, null , res.error.details); return true ; } } let broker = new ServiceBroker({ logger: true , validator: new JoiValidator }); broker.createService({ name: "greeter" , actions: { hello: { params: Joi.object().keys({ name: Joi.string().min(4 ).max(30 ).required() }), handler(ctx) { return `Hello ${ctx.params.name} ` ; } } } }); broker.start() .then(() => broker.call("greeter.hello" ).then(res => broker.logger.info(res))) .catch(err => broker.logger.error(err.message, err.data)) .then(() => broker.call("greeter.hello" , { name : 100 }).then(res => broker.logger.info(res))) .catch(err => broker.logger.error(err.message, err.data)) .then(() => broker.call("greeter.hello" , { name : "Joe" }).then(res => broker.logger.info(res))) .catch(err => broker.logger.error(err.message, err.data)) .then(() => broker.call("greeter.hello" , { name : "John" }).then(res => broker.logger.info(res))) .catch(err => broker.logger.error(err.message, err.data));
Find more validators 可从模块页面找到更多验证器。