首页 > 解决方案 > 是否可以创建具有许多 Validator 实例的分子服务?

问题描述

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

像这样的东西:

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

标签: moleculer

解决方案


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

"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它从 the 中读取,ctx.meta.lang但您可以根据自己的情况进行更改。


推荐阅读