Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Валидация с VineJS

Данным из формы нельзя доверять: заголовок могут оставить пустым, а в поле числа прислать текст. Валидация — проверка входящих данных по правилам до того, как они попадут в базу. В AdonisJS для этого используют библиотеку VineJS: правила описываются схемой, а результат проверки получает точные типы TypeScript.

Создание валидатора

node ace make:validator post

Появится файл app/validators/post.ts. Опишите правила для новой статьи:

// app/validators/post.ts
import vine from '@vinejs/vine'
 
export const createPostValidator = vine.compile(
  vine.object({
    title: vine.string().trim().minLength(3).maxLength(255),
    body: vine.string().trim().minLength(10),
  })
)

vine.object описывает ожидаемые поля, vine.string() требует строку, а trim, minLength и maxLength уточняют правила. vine.compile один раз превращает схему в быструю функцию проверки. По умолчанию все поля обязательны.

Проверка в контроллере

// app/controllers/posts_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
import Post from '#models/post'
import { createPostValidator } from '#validators/post'
 
export default class PostsController {
  async store({ request, response }: HttpContext) {
    const payload = await request.validateUsing(createPostValidator)
    const post = await Post.create(payload)
    return response.redirect().toRoute('posts.show', { id: post.id })
  }
}

validateUsing берёт данные запроса и проверяет их. Если всё верно, payload содержит только описанные поля с типом { title: string; body: string }. Лишние поля, например isAdmin, в него не попадут.

Что происходит при ошибке

Если проверка не прошла, код после validateUsing не выполняется. Дальше AdonisJS действует по типу запроса:

ЗапросОтвет
Обычная HTML-формаРедирект назад, ошибки и введённые значения сохраняются в сессии
JSON-запрос (заголовок Accept: application/json)Статус 422 и JSON со списком ошибок

Как показать ошибки рядом с полями формы, разобрано в следующем уроке.

Частые правила

ПравилоЧто проверяет
vine.string().email()Адрес почты
vine.number().min(1)Число не меньше 1
vine.boolean()Да или нет, в том числе флажок формы
vine.enum(['draft', 'published'])Одно из значений
vine.string().optional()Поле можно не передавать
vine.string().confirmed()Совпадение с полем ..._confirmation

Сообщения на русском

Стандартные сообщения VineJS — на английском. Свои тексты задают провайдером сообщений. Создайте файл предзагрузки командой node ace make:preload validator и запишите в него:

// start/validator.ts
import vine, { SimpleMessagesProvider } from '@vinejs/vine'
 
vine.messagesProvider = new SimpleMessagesProvider({
  'required': 'Поле {{ field }} обязательно',
  'minLength': 'Поле {{ field }} должно быть не короче {{ min }} символов',
  'title.minLength': 'Заголовок слишком короткий',
})

Ключ title.minLength задаёт сообщение для одного поля и одного правила, а общий minLength — для всех остальных.

Частая ошибка

Валидатор создают внутри метода контроллера: const validator = vine.compile(...) прямо в store. Тогда схема компилируется заново при каждом запросе, и это заметно замедляет приложение. Объявляйте валидаторы в app/validators/ на верхнем уровне модуля, а в контроллер импортируйте готовые.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.