是否可以使用许多Validator实例创建一个Molecularr服务?

时间:2019-01-07 00:55:55

标签: moleculer

我想在我的服务上拥有多个Validator实例来处理不同的语言。有什么办法可以实现?

类似的东西:

 {
    en: new Validator({ messages: { ... }}),
    de: new Validator({ messages: { ... }})
    // ...
 }

1 个答案:

答案 0 :(得分:1)

不可用。您应该创建一个自定义的多重验证器。这是一个简单的示例:

"use strict";

const _ = require("lodash");
const { ServiceBroker } = require("moleculer");
const BaseValidator = require("moleculer").Validators.Base;
const Validator = require("fastest-validator");
const DefaultMessages = require("fastest-validator/lib/messages");
const { ValidationError } = require("moleculer").Errors;

// --- I18N VALIDATOR CLASS ---
class I18NValidator extends BaseValidator {
    constructor(messages) {
        super();
        0;
        this.validators = {};
        Object.keys(messages).forEach(lang => {
            this.validators[lang] = new Validator();
            this.validators[lang].messages = Object.assign({}, DefaultMessages, messages[lang]);
        });
    }

    compile(schema) {
        this.checks = {};
        Object.keys(this.validators).forEach(lang => {
            this.checks[lang] = this.validators[lang].compile(schema);
        });
        return this.checks;
    }

    middleware() {
        return function I18NValidator(handler, action) {
            // Wrap a param validator
            if (action.params && typeof action.params === "object") {
                const checks = this.compile(action.params);
                return function validateContextParams(ctx) {
                    const check = checks[ctx.meta.lang] || checks["en"];
                    const res = check(ctx.params);
                    if (res === true)
                        return handler(ctx);
                    else
                        return Promise.reject(new ValidationError("Parameters validation error!", null, res));
                };
            }
            return handler;
        }.bind(this);
    }
}

let broker = new ServiceBroker({
    logger: true,
    validation: true,
    validator: new I18NValidator({
        "en": {
            "string": "The '{field}' field must be a string!"
        },
        "hu": {
            "string": "A '{field}' mezőnek szövegnek kell lennie!"
        }
    })
});

// --- TEST BROKER ---

broker.createService({
    name: "greeter",
    actions: {
        hello: {
            params: {
                name: { type: "string", min: 4 }
            },
            handler(ctx) {
                return `Hello ${ctx.params.name}`;
            }
        }
    }
});

broker.start()
    // No meta lang
    .then(() => broker.call("greeter.hello", { name: 100 }).then(res => broker.logger.info(res)))
    .catch(err => broker.logger.error(err.message, err.data))
    // "hu" lang
    .then(() => broker.call("greeter.hello", { name: 100 }, { meta: { lang: "hu" }}).then(res => broker.logger.info(res)))
    .catch(err => broker.logger.error(err.message, err.data))
    // "en" lang
    .then(() => broker.call("greeter.hello", { name: 100 }, { meta: { lang: "en" }}).then(res => broker.logger.info(res)))
    .catch(err => broker.logger.error(err.message, err.data));

它从lang读取ctx.meta.lang,但是您可以根据情况进行更改。