SlideShare a Scribd company logo
1 of 18
Download to read offline
Серверная	валидация	сложных	форм	
и	ее	синхронизация	с	фронтендом
на	примере	Ajv
Александр	Сафт
@fend25
SPA	Meetup
Москва,	8	апреля	2017	года
Проверка	данных
ВАЛИДАЦИЯ	— (от	лат.	validus сильный)
признание	чего-либо	законным,	действительным.
ВЕРИФИКАЦИЯ	— (от	лат.	лат.	verus истинный	+	facere делать)
свидетельство,	удостоверение	в	подлинности.
Словарь	иностранных	слов,	вошедших	в	состав	русского	языка.	
Чудинов А.Н.,	1910
Классификация	проверки	данных
Валидация
Верификация
Тип
Классификация	проверки	данных
На	клиенте На сервере
Валидация
Верификация
МестоТип
Классификация	проверки	данных
На	клиенте На сервере
Валидация ↔
Верификация
МестоТип
Валидация	и	верификация
Backend:
• Два	отдельных	процесса
• Валидация – на	старте	
хендлера
• Верификация	– может	быть	
размазана	тонким	слоем	по	
всему	хендлеру
Frontend:
• Как	правило,	в	одном	месте
• Валидация	и	верификация	
слиты
• Выполняются	в	лучшем	случае	
последовательно	(могут	быть	
смешаны)
Клиентская	валидация
Angular Redux-form
Клиентская	валидация	- перспектива
React-redux-form form2
Серверная	валидация	- встроенная
app.post('/register', function(req, res) {
req.Validator
.validate('username', i18n.t('user.displayName'), {length: {min: 3, max: 256})
.filter('username', {trim: true})
.validate('password', {length: {min: 4, max: 64}})
.filter('password', {stripTags: false, escapeHTML: false});
req.Validator.getErrors(function(errors){ ... });
});
Серверная	валидация	- отдельная
Своя	схема - Joi
Json	Schema
const schema = Joi.object().keys({
username: Joi.string().alphanum().min(3).max(30).required(),
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
access_token: [Joi.string(), Joi.number()],
email: Joi.string().email()
}).with('username').without('password', 'access_token');
const schema = {
type: 'object',
properties: {
username: {type: 'string', format: 'alphanum', minLength:3, maxLength:30},
password: {type: 'string', regex: /^[a-zA-Z0-9]{3,30}$/},
access_token: {oneOf: [{type: 'string'}, {type: 'number'}]},
email: {type: 'string', format: 'email'}
},
required: ['username']
}
Серверная	валидация	- хелперы
До После
const userSchema = toAjvObject({
name: ct.notEmptyString,
email: ct.email,
dateOfBirth: ct.date,
about: ct.stringOrNull
})
const userSchema = {
type: 'object',
properties: {
name: {type: 'string', minLength: 1},
email: {type: 'string', format: 'email'},
dateOfBirth: {type: 'string', format: 'date'},
about: {oneOf: [{type: 'string'}, {type: 'null'}]}
},
required: ['name', 'email', 'dateOfBirth', 'about']
}
Серверная	валидация – API
Допустим,	API	должно	уметь	выполнять	три	действия:
1. Добавить		пользователя
2. Обновить	пользователя
3. Создать	бронирование	с	новыми	пользователями
const commands = {
CREATE_USER: 'CREATE_USER',
UPDATE_USER: 'UPDATE_USER',
CREATE_BOOKING: 'CREATE_BOOKING'
}
Серверная	валидация – API
// create user
const userSchema = {
name: ct.notEmptyString,
email: ct.email
}
schemas.saveValidator(commands.CREATE_USER, toAjvObject(userSchema))
// update user
const userWithIdSchema = addIntId(userSchema)
schemas.saveValidator(commands.UPDATE_USER, toAjvObject(userWithIdSchema))
// create booking
const createBookingSchema = {
startTs: ct.datetime,
users: toAjvArray(toAjvObject(userSchema))
}
schemas.saveValidator(commands.CREATE_BOOKING, toAjvObject(createBookingSchema))
Серверная	валидация – API
function saveValidator(cmdCode, schema) {
validators.raw[cmdCode] = schema
validators.compiled[cmdCode] = ajv.compile(schema)
}
// create booking
const createBookingSchema = {
startTs: ct.datetime,
users: toAjvArray(toAjvObject(userSchema))
}
schemas.saveValidator(commands.CREATE_BOOKING, toAjvObject(createBookingSchema))
Серверная	валидация – API
{
"type": "object",
"properties": {
"startTs": {"type": "string", "format": "date-time"},
"users": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"email": {"type": "string", "format": "email"},
"dateOfBirth": {"type": "string", "format": "date"},
"about": {"oneOf": [{"type": "string"},{"type": "null"}]}
},
"required": ["name", "email", "dateOfBirth","about"]
}
}
},
"required": ["startTs", "users"]
}
Синхронизированная	валидация
Валидаторы можно	передать	на	клиентскую	часть.
Валидация	и	верификация	на	клиенте	таким	образом	разделяются.
Часть	верификации	может	быть	вынесена	также	в	схему	при	помощи	
расширений	JSON	Schema.	Дело	вкуса,	и	выбирается	по	проекту	и	от	
желаний	разработчиков.
Минус:	при	передаче	валидатора нужно	самостоятельно	написать	
обвязку	для	генерации	сообщений	об	ошибках.	В	некоторой	степени	
эта	задача	облегчается	четкостью	структуры	ошибок	Ajv.
Выводы
1. JS	– язык,	который	позволяет	на	пустом	месте	
создать	экземпляр	любого	объекта/структуры	и	
ничего	за	это	не	будет*
2. Из-за	этого	часто	выходит	лапша,	которую	потом	
долго	и	нудно	рефакторить
3. Если	лапшу	держать	в	крепких	объятиях	оберток	и	
хелперов,	а	все	что	можно	– выносить	в	общие	
константы,	то	на	выходе	получится	лаконичный	и	
гибкий	код,	с	которым	будет	приятно	работать.
*	кроме		Cannot read property 'x' of undefined
Спасибо	за	внимание
Александр	Сафт
@fend25

More Related Content

More from AvitoTech

Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
AvitoTech
 
Машинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
Машинное обучение в Дзене - Евгений Соколов и Дмитрий УшановМашинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
Машинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
AvitoTech
 

More from AvitoTech (20)

SimplePEG - Алексей Охрименко
SimplePEG - Алексей ОхрименкоSimplePEG - Алексей Охрименко
SimplePEG - Алексей Охрименко
 
Как перестать бояться и начать контрибьютить - Алексей Кудрявцев
 Как перестать бояться и начать контрибьютить - Алексей Кудрявцев Как перестать бояться и начать контрибьютить - Алексей Кудрявцев
Как перестать бояться и начать контрибьютить - Алексей Кудрявцев
 
"Анонимизация фото с помощью Vision", Хомутников Тимофей, Avito
"Анонимизация фото с помощью Vision",  Хомутников Тимофей, Avito"Анонимизация фото с помощью Vision",  Хомутников Тимофей, Avito
"Анонимизация фото с помощью Vision", Хомутников Тимофей, Avito
 
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
“iOS 11 в App in the Air”, Пронин Сергей, App in the Air
 
"ARKit в приложении Афиша Рестораны”, Меджлумян Самвел, Антышев Дмитрий, Ramb...
"ARKit в приложении Афиша Рестораны”, Меджлумян Самвел, Антышев Дмитрий, Ramb..."ARKit в приложении Афиша Рестораны”, Меджлумян Самвел, Антышев Дмитрий, Ramb...
"ARKit в приложении Афиша Рестораны”, Меджлумян Самвел, Антышев Дмитрий, Ramb...
 
ASO for iOS 11
ASO for iOS 11ASO for iOS 11
ASO for iOS 11
 
Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
Добиваемся эффективности каждого из 9000+ UI-тестов - Максим Сахаров (Tutu.ru)
 
Проблемы управления тестами, или Что мешает создавать дешевые и полезные тест...
Проблемы управления тестами, или Что мешает создавать дешевые и полезные тест...Проблемы управления тестами, или Что мешает создавать дешевые и полезные тест...
Проблемы управления тестами, или Что мешает создавать дешевые и полезные тест...
 
Запускаем тесты в Continuous Integration - Сергей Пак (JetBrains)
Запускаем тесты в Continuous Integration - Сергей Пак (JetBrains)Запускаем тесты в Continuous Integration - Сергей Пак (JetBrains)
Запускаем тесты в Continuous Integration - Сергей Пак (JetBrains)
 
Векторы развития систем автоматизации тестирования - Дмитрий Химион (Avito)
Векторы развития систем автоматизации тестирования - Дмитрий Химион (Avito)Векторы развития систем автоматизации тестирования - Дмитрий Химион (Avito)
Векторы развития систем автоматизации тестирования - Дмитрий Химион (Avito)
 
Прокачиваем WebDriverAgent, или Как тестировать iOS-приложения после ядерного...
Прокачиваем WebDriverAgent, или Как тестировать iOS-приложения после ядерного...Прокачиваем WebDriverAgent, или Как тестировать iOS-приложения после ядерного...
Прокачиваем WebDriverAgent, или Как тестировать iOS-приложения после ядерного...
 
Конкурс Авито-2017 - Решение 2ое место - Василий Рубцов
Конкурс Авито-2017 - Решение 2ое место - Василий РубцовКонкурс Авито-2017 - Решение 2ое место - Василий Рубцов
Конкурс Авито-2017 - Решение 2ое место - Василий Рубцов
 
Конкурс Авито-2017 - Решение 3ое место
Конкурс Авито-2017 - Решение 3ое местоКонкурс Авито-2017 - Решение 3ое место
Конкурс Авито-2017 - Решение 3ое место
 
Конкурс Авито-2017 - Решение победителя
Конкурс Авито-2017 - Решение победителяКонкурс Авито-2017 - Решение победителя
Конкурс Авито-2017 - Решение победителя
 
Avito Recommendations Contest - Михаил Каменщиков
Avito Recommendations Contest - Михаил КаменщиковAvito Recommendations Contest - Михаил Каменщиков
Avito Recommendations Contest - Михаил Каменщиков
 
Какие задачи решает команда рекомендаций в Avito - Василий Лексин
Какие задачи решает команда рекомендаций в Avito - Василий ЛексинКакие задачи решает команда рекомендаций в Avito - Василий Лексин
Какие задачи решает команда рекомендаций в Avito - Василий Лексин
 
Рекомендации в OZON.ru - Ксения Бокша
Рекомендации в OZON.ru - Ксения БокшаРекомендации в OZON.ru - Ксения Бокша
Рекомендации в OZON.ru - Ксения Бокша
 
Машинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
Машинное обучение в Дзене - Евгений Соколов и Дмитрий УшановМашинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
Машинное обучение в Дзене - Евгений Соколов и Дмитрий Ушанов
 
Стабы для фронтенда - Никита Мостовой (HeadHunter)
Стабы для фронтенда - Никита Мостовой (HeadHunter)Стабы для фронтенда - Никита Мостовой (HeadHunter)
Стабы для фронтенда - Никита Мостовой (HeadHunter)
 
Работаем с API по-взрослому - Максим Кислов (Badoo)
Работаем с API по-взрослому - Максим Кислов (Badoo)Работаем с API по-взрослому - Максим Кислов (Badoo)
Работаем с API по-взрослому - Максим Кислов (Badoo)
 

Серверная валидация сложных форм и ее синхронизация с фронтендом на примере Ajv - Александр Сафт (Zeeng)