V for Validator

Автор: admin от 8-02-2018, 07:15, посмотрело: 180

Когда перед нами стоит выбор инструмента для валидации пользовательских данных, то речь чаще идет о интерфейсе задания правил. Сегодня таких инструментов превеликое множество от декларативных до объектных. Каждый валидатор пытается быть выразительным и простым в использовании. Но я хочу обратить ваше внимание на результат работы валидатора – отчеты. Каждый разработчик норовит сделать свое решение и если для интерфейсов от разнообразия лишь польза, то для получаемого результата наоборот. В общем, давайте взглянем на проблему.



Осторожно! После прочтения статьи вы, возможно, захотите выкинуть ваш любимый валидатор.
jsbin.



Библиотечные функции



Здесь будут реализованы два метода для создания Issue (createIssue) и для добавления префикса к значению Issue.path (pathRefixer):



function createIssue(path, rule, details = {}) {
    return {path, rule, details};
}

function pathPrefixer(...prefix) {
    return ({path, rule, details}) => ({
        path: [...prefix, ...path],
        rule,
        details,
    });
}


Валидатор логина



Собственно тот самый валидатор логина.



const LETTER = /[a-z]/;
const NUMBER = /[0-9]/;

function validCharsLength(login) {
    let i;
    for (i = 0; i < login.length; i++) {
        const char = login[i];

        if (i === 0) {
            if (! LETTER.test(char)) {
                break;
            }
        }
        else {
            if (! LETTER.test(char) && ! NUMBER.test(char)) {
                break;
            }
        }
    }

    return i;
}

function validateLogin(login) {
    const validLength = validCharsLength(login);

    if (validLength < login.length) {
        return [
            createIssue([], 'syntax', {
                pos: validLength,
                expect: validLength > 0 ? ['NUMBER', 'LETTER'] : ['LETTER'],
                is: login.slice(validLength, validLength + 1),
            }),
        ];
    }
    else {
        return [];
    }
}

function stringifySyntaxIssue({details}) {
  return `Invalid character "${details.is}" at postion ${details.pos}.`;
}


Имплементация



Реализация на уровне приложения. Добавляем функцию проверки модели и абстрактного запроса использующего модель:



function validateUser(user) {
    return validateSyntax(user.login)
    .map(pathPrefixer('login'));
}

function validateUsersRequest(request) {
    return request.users
    .reduce((reports, user, i) => {
        const report = validateUser(user)
        .map(pathPrefixer('users', i));

        return [...reports, ...report];
    }, []);
}

const usersRequest = {
    users: [
        {login: 'adm!n'},
        {login: 'u$er'},
        {login: '&@%#'},
    ],
};

function stringifyLoginSyntaxIssue(issue) {
    return `User #${issue.path[1]} login: ${stringifySyntaxIssue(issue)}`;
}

const report = validateUsersRequest(usersRequest);

const loginSyntaxIssues = report.filter(
  ({path, rule}) => path[2] === 'login' && rule === 'syntax'
);

console.log(report);
console.log(loginSyntaxIssues.map(stringifyLoginSyntaxIssue).join('n'));


Заключение



Использование ValidationReport позволит комбинировать различные библиотеки для валидации и управлять процессом на свое усмотрение: например выполнить трудоемкие проверки параллельно, а затем конкатенировать результат. Отчеты от разных программ представляются однотипно и позволяют переиспользовать код их обработчиков.



Реализация



На сегодняшний день существует пакет для nodejs:





Источник: Хабрахабр

Категория: Программирование

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *