Валидация данных

Fresh — это современный фреймворк для разработки веб-приложений на JavaScript и TypeScript, который ориентирован на быстрый рендеринг на сервере и минимальное использование клиентского JavaScript. Одним из ключевых аспектов работы с Fresh является взаимодействие с данными и их валидация, что обеспечивает безопасность и корректность работы приложений.


Взаимодействие с данными в Fresh

В Fresh данные передаются между сервером и клиентом преимущественно через объекты props и state. Данные могут поступать из различных источников:

  • REST API или GraphQL;
  • базы данных;
  • форм пользовательского ввода;
  • внешние сервисы.

Важно понимать, что данные, получаемые извне, всегда потенциально небезопасны и требуют проверки перед использованием. Fresh не накладывает строгих ограничений на структуру данных, поэтому ответственность за их валидацию лежит на разработчике.


Основы валидации данных

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

  1. Простая проверка типов
function validateUser(user) {
  if (typeof user.name !== 'string') {
    throw new Error('Имя должно быть строкой');
  }
  if (typeof user.age !== 'number') {
    throw new Error('Возраст должен быть числом');
  }
  return true;
}
  1. Проверка с использованием регулярных выражений
function validateEmail(email) {
  const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!pattern.test(email)) {
    throw new Error('Неверный формат email');
  }
  return true;
}
  1. Валидация с использованием сторонних библиотек

Наиболее популярными библиотеками для валидации в Fresh являются:

  • zod — для строгой схемной валидации;
  • yup — для декларативной проверки объектов и форм.

Пример с zod:

import { z } from "zod";

const userSchema = z.object({
  name: z.string().min(1, "Имя не может быть пустым"),
  age: z.number().int().positive("Возраст должен быть положительным"),
  email: z.string().email("Неверный формат email")
});

function validateUserData(data) {
  return userSchema.parse(data); // выбрасывает ошибку при некорректных данных
}

Валидация форм в Fresh

Fresh активно использует серверные обработчики (Handlers) для обработки форм. Валидация на сервере позволяет защитить приложение даже если клиентский JavaScript отключен или изменён.

Пример серверного хэндлера с валидацией формы:

export const handler = {
  async POST(req) {
    const formData = await req.formData();
    const data = {
      name: formData.get("name"),
      age: Number(formData.get("age")),
      email: formData.get("email")
    };

    try {
      validateUserData(data); // использование схемы Zod
      // обработка данных (сохранение в БД, отправка письма и т.д.)
      return new Response("Данные успешно обработаны", { status: 200 });
    } catch (err) {
      return new Response(`Ошибка: ${err.message}`, { status: 400 });
    }
  }
};

Клиентская валидация

Хотя серверная валидация является обязательной, клиентская позволяет улучшить UX, предотвращая отправку некорректных данных:

function handleSubmit(event) {
  event.preventDefault();
  const formData = new FormData(event.target);
  const data = {
    name: formData.get("name"),
    age: Number(formData.get("age")),
    email: formData.get("email")
  };

  try {
    validateUserData(data);
    fetch("/api/submit", { method: "POST", body: formData });
  } catch (err) {
    alert(err.message);
  }
}

Безопасность данных и защита от атак

Валидация в Fresh помогает защититься от:

  • SQL-инъекций — корректная проверка типов и формата данных перед отправкой в базу данных;
  • XSS (Cross-Site Scripting) — проверка и экранирование пользовательского ввода перед рендерингом в HTML;
  • CSRF (Cross-Site Request Forgery) — использование токенов и серверной проверки форм.

Использование схемной валидации, таких как zod, позволяет объединить валидаторы типов, форматов и значений в единый объект, упрощая поддержку и тестирование кода.


Практика работы с Fresh и валидацией

  1. Определять схему данных для каждой формы или API-запроса.
  2. Проверять все данные на сервере, независимо от клиентской валидации.
  3. Использовать специализированные библиотеки (zod, yup) для сложных структур и вложенных объектов.
  4. Логировать ошибки валидации для анализа, не раскрывая пользователю внутренних деталей.
  5. Поддерживать единообразие форматов и типов данных в проекте для предотвращения неожиданных ошибок.

Интеграция с базой данных

При работе с Fresh и базой данных важна валидация перед записью данных:

import { db } from "./db.js";

async function saveUser(data) {
  const validated = validateUserData(data); 
  await db.insert("users", validated);
}

Такой подход гарантирует, что в базе будут храниться только корректные данные, а бизнес-логика приложения останется устойчивой.


Вывод

Валидация данных в Fresh — ключевой элемент безопасного и стабильного приложения. Сочетание серверной проверки, схемной валидации и клиентской проверки обеспечивает целостность данных, защиту от уязвимостей и упрощает масштабирование приложения. Применение инструментов вроде zod или yup позволяет создавать предсказуемые, структурированные и легко поддерживаемые системы.