Описание схемы параметров и результатов роутов

Введение

Новый API для описания схем роутов в Chatium предоставляет типобезопасный и удобный способ определения валидации
параметров запросов и ответов. API вдохновлен популярной библиотекой Zod и предоставляет похожий
синтаксис, сохраняя при этом обратную совместимость с существующим кодом.

Основные преимущества

1. Полная типобезопасность

Все параметры и возвращаемые значения автоматически типизируются TypeScript, что обеспечивает:

  • Автокомплит в IDE
  • Проверку типов на этапе компиляции
  • Отсутствие runtime ошибок из-за несоответствия типов

2. Fluent API

Интуитивный цепочечный синтаксис делает код более читаемым и компактным:

app
  .post('/users')
  .body(s => ({
    name: s.string().min(1),
    email: s.string().email(),
    age: s.number().optional(),
  }))
  .result(s => ({
    id: s.string(),
    createdAt: s.date(),
  }))
  .handle(async (ctx, req) => {
    // req.body полностью типизирован
    const user = await createUser(ctx, req.body)
    return user
  })

3. Единый подход для всех типов роутов

Один и тот же API работает для:

  • HTTP роутов (GET, POST)
  • UI роутов (screen, html)
  • Внутренних роутов (job, function)

4. Обратная совместимость

Новый формат полностью совместим со старым API на основе Heap.* типов. Вы можете постепенно мигрировать существующий
код.

Быстрый старт

Импорт необходимых модулей

Простейший GET роут

export const getUser = app
  .get('/users/:id')
  .pathParams(s => ({ id: s.string() }))
  .result(s => ({
    id: s.string(),
    name: s.string(),
    email: s.string(),
  }))
  .handle(async (ctx, req) => {
    const user = await userRepo.findById(ctx, req.params.id)
    return user
  })

Простейший POST роут

export const createUser = app
  .post('/users')
  .body(s => ({
    name: s.string(),
    email: s.string().email(),
  }))
  .result(s => ({
    id: s.string(),
    success: s.boolean(),
  }))
  .handle(async (ctx, req) => {
    const user = await userRepo.create(ctx, req.body)
    return { id: user.id, success: true }
  })

Описание схем вне роутов

Для удобства можно описывать схемы отдельно и использовать их в нескольких роутов:

import { s } from '@app/schema'
// s - это SchemaBuilder для создания схем валидации

const userSchema = s.object({
  id: s.string(),
  name: s.string(),
  email: s.string().email(),
})

export const getUser = app
  .get('/users/:id')
  .pathParams({ id: s.string() })
  .result(userSchema)
  .handle(async (ctx, req) => {
    const user = await userRepo.findById(ctx, req.params.id)
    return user
  })

Структура документации

  1. Основные концепции - Понимание ключевых идей нового API
  2. Базовые типы схем - Строки, числа, даты и другие простые типы
  3. Составные типы - Объекты, массивы, кортежи
  4. Специальные типы - Файлы, деньги, ссылки на роуты
  5. Модификаторы типов - optional, nullable, default
  6. Методы описания роутов - body, query, pathParams, result
  7. Типы роутов - GET, POST, screen, job и другие
  8. Middleware и метаданные - Расширение функциональности роутов
  9. RouteRef и вызов роутов - Использование роутов в коде
  10. Миграция со старого формата - Пошаговое руководство
  11. Примеры использования - Практические примеры
  12. Решение проблем - Частые ошибки и их решения

Следующие шаги

Перейдите к разделу Основные концепции для более глубокого понимания нового API.