Метод rename() в библиотеке Joi предназначен для
переименования полей объекта до выполнения основной валидации. Это
особенно полезно при:
snake_case,
camelCase);schema.rename(from, to, [options])
| Аргумент | Описание |
|---|---|
from |
Исходное имя поля |
to |
Новое имя поля |
options |
Дополнительные параметры поведения |
const Joi = require('joi');
const schema = Joi.object({
username: Joi.string().required()
}).rename('user_name', 'username');
const data = {
user_name: 'alex'
};
const result = schema.validate(data);
console.log(result.value);
Результат:
{
username: 'alex'
}
Поле user_name автоматически преобразуется в
username ещё до запуска основной схемы валидации.
Переименование выполняется в несколько этапов:
from.to.Это означает, что схема никогда не увидит исходное имя поля.
const schema = Joi.object({
firstName: Joi.string(),
lastName: Joi.string()
})
.rename('first_name', 'firstName')
.rename('last_name', 'lastName');
Входные данные:
{
first_name: 'John',
last_name: 'Doe'
}
После обработки:
{
firstName: 'John',
lastName: 'Doe'
}
optionsМетод rename() поддерживает объект настроек:
.rename(from, to, {
alias,
multiple,
override,
ignoreUndefined
})
aliasБез alias старое поле удаляется.
const schema = Joi.object({
login: Joi.string()
}).rename('username', 'login');
Вход:
{
username: 'admin'
}
Результат:
{
login: 'admin'
}
Поле username исчезает.
const schema = Joi.object({
login: Joi.string()
}).rename('username', 'login', {
alias: true
});
Результат:
{
username: 'admin',
login: 'admin'
}
Теперь создаётся копия вместо переноса.
aliasconst schema = Joi.object({
email: Joi.string().email()
}).rename('mail', 'email', {
alias: true
});
Старые клиенты используют mail, новые —
email.
multipleПо умолчанию Joi запрещает нескольким полям переименовываться в один ключ.
const schema = Joi.object({
name: Joi.string()
})
.rename('username', 'name')
.rename('login', 'name');
Вход:
{
username: 'alex',
login: 'root'
}
Ошибка:
Error: Cannot rename "login" because multiple renames are disabled
const schema = Joi.object({
name: Joi.string()
})
.rename('username', 'name', {
multiple: true
})
.rename('login', 'name', {
multiple: true
});
Последнее переименование перезаписывает предыдущее.
{
username: 'alex',
login: 'root'
}
Результат:
{
name: 'root'
}
overrideЕсли целевой ключ уже существует, Joi выбрасывает ошибку.
const schema = Joi.object({
name: Joi.string()
}).rename('username', 'name');
Вход:
{
username: 'alex',
name: 'admin'
}
Ошибка:
Error: Cannot rename "username" because override is disabled
const schema = Joi.object({
name: Joi.string()
}).rename('username', 'name', {
override: true
});
Результат:
{
name: 'alex'
}
Старое значение name будет уничтожено.
ignoreUndefinedЕсли поле отсутствует, Joi может выбрасывать ошибку в определённых сценариях.
.rename('oldField', 'newField')
.rename('oldField', 'newField', {
ignoreUndefined: true
})
Теперь отсутствие oldField не вызывает проблем.
Это одна из важнейших особенностей rename().
const schema = Joi.object({
age: Joi.number().integer().min(18)
}).rename('user_age', 'age');
Вход:
{
user_age: 25
}
Сначала выполняется:
{
age: 25
}
И только затем запускается:
Joi.number().integer().min(18)
const schema = Joi.object({
profile: Joi.object({
firstName: Joi.string()
}).rename('first_name', 'firstName')
});
{
profile: {
first_name: 'Alex'
}
}
Результат:
{
profile: {
firstName: 'Alex'
}
}
rename() поддерживает переименование через
RegExp.
const schema = Joi.object()
.rename(/^(\w+)_id$/, Joi.ex * pression('{#1}Id'));
Вход:
{
user_id: 1,
product_id: 20
}
Результат:
{
userId: 1,
productId: 20
}
Метод Joi.ex * pression() позволяет использовать шаблоны
при генерации нового имени.
Joi.ex * pression('{#1}Id')
#1 — первая группа регулярного выражения.
const schema = Joi.object()
.rename(
/^api_(\w+)_(\w+)$/,
Joi.ex * pression('{#1}.{#2}')
);
Вход:
{
api_user_name: 'Alex'
}
Результат:
{
'user.name': 'Alex'
}
Одна из самых популярных задач.
const schema = Joi.object({
firstName: Joi.string(),
lastName: Joi.string()
})
.rename('first_name', 'firstName')
.rename('last_name', 'lastName');
const schema = Joi.object()
.rename(
/^(\w+)_(\w+)$/,
Joi.ex * pression('{#1}{#2}')
);
Однако такой вариант не преобразует буквы в верхний регистр.
Для настоящего camelCase обычно используют
предварительную обработку данных перед Joi.
unknown()Часто rename() применяется вместе с разрешением
неизвестных ключей.
const schema = Joi.object({
username: Joi.string()
})
.rename('user_name', 'username')
.unknown(true);
Порядок методов имеет значение.
Joi.object()
.rename('a', 'b')
.rename('b', 'c');
Вход:
{
a: 1
}
Результат:
{
c: 1
}
Переименование выполняется последовательно.
const schema = Joi.object()
.rename('fname', 'first_name')
.rename('first_name', 'firstName');
Результат:
{
firstName: 'John'
}
rename(){
name: 'admin',
username: 'alex'
}
При переименовании username -> name возникает
конфликт.
override: true
может уничтожить существующие значения.
.rename('a', 'b')
.rename('b', 'c')
.rename('c', 'd')
Сложные каскады ухудшают читаемость схемы.
{
user_name: 'alex',
user_mail: 'alex@example.com'
}
{
username: 'alex',
email: 'alex@example.com'
}
const schema = Joi.object({
username: Joi.string().required(),
email: Joi.string().email().required()
})
.rename('user_name', 'username')
.rename('user_mail', 'email');
{
fullname: 'John Doe'
}
{
fullName: 'John Doe'
}
const schema = Joi.object({
fullName: Joi.string()
})
.rename('fullname', 'fullName', {
alias: true
});
strip()Иногда требуется переименовать поле и удалить старые данные.
const schema = Joi.object({
password: Joi.string(),
oldPassword: Joi.string().strip()
})
.rename('old_password', 'oldPassword');
when()После переименования поле участвует в условной логике уже под новым именем.
const schema = Joi.object({
role: Joi.string(),
permissions: Joi.array().when('role', {
is: 'admin',
then: Joi.required()
})
})
.rename('user_role', 'role');
prefs()const schema = Joi.object({
username: Joi.string()
})
.rename('user_name', 'username')
.prefs({
abortEarly: false
});
Переименование никак не влияет на глобальные настройки схемы.
rename() работает быстро, однако большое количество
переименований может:
rename()
когда:rename()
когда:const Joi = require('joi');
const schema = Joi.object({
firstName: Joi.string().required(),
lastName: Joi.string().required(),
age: Joi.number().integer().min(18)
})
.rename('first_name', 'firstName')
.rename('last_name', 'lastName')
.rename('user_age', 'age');
const data = {
first_name: 'Alex',
last_name: 'Doe',
user_age: 25
};
const result = schema.validate(data);
console.log(result.value);
Результат:
{
firstName: 'Alex',
lastName: 'Doe',
age: 25
}