TGViewer
ТОП - Тёма о программировани ТОП - Тёма о программировани @temaprog · 2.81K subscribers
Post #130 2.1K
Здарова, работяги!

Сегодня разберёмся, в чём боль code-first, что меняет schema-first и как это выглядит в Fastify.

Code-first

Правила формы данных живут в коде, рассыпанные по разным местам. Валидация — отдельная функция. Типы — отдельный интерфейс. Обе сущности — копии одной и той же правды в разных синтаксисах.

Знакомая картина — ручная валидация формы:


function validateUserForm(values) {
const errors = {}
if (!values.email) errors.email = 'required'
if (!values.age || Number.isNaN(+values.age)) errors.age = 'must be number'
return errors
}

// где-то рядом
type UserForm = { email: string; age: number }


Два источника правды на одну сущность. Один обновил — другой забыл. Дальше прод, неприятный сюрприз, разбор полётов в Slack.

Schema-first

Подход, при котором описание формы данных живёт отдельно от бизнес-логики и является источником правды. Описываем форму декларативно — например, объектом JSON Schema. Дальше из этого объекта получаются:

— валидация входа (запрос проверяется по схеме до того, как попадёт в обработчик);
— сериализация выхода (ответ режется по схеме, лишние поля не уйдут наружу);
— TypeScript-типы (генерятся из схемы — например, через TypeBox или json-schema-to-ts).

Одна декларация — три артефакта. Обновил схему — всё остальное само догнало.

Как это в Fastify

Fastify построен вокруг schema-first из коробки. Минимальный пример:


const schema = {
body: {
type: 'object',
required: ['email', 'age'],
properties: {
email: { type: 'string', format: 'email' },
age: { type: 'integer' }
},
additionalProperties: false
},
response: {
201: {
type: 'object',
properties: {
id: { type: 'integer' },
email: { type: 'string' }
}
}
}
}

fastify.post('/users', { schema }, async (req, reply) => {
const user = await db.users.insert(req.body)
reply.code(201).send(user)
})


Что мы получили бесплатно:

— request body валидируется до обработчика. Невалидный — 400 с понятным сообщением, обработчик даже не дёргается;
— response сериализуется по схеме. Если в user внезапно прилетело password_hash — он не уйдёт наружу. Это и про безопасность, и про предсказуемость контракта;
— additionalProperties: false режет лишние поля на входе. Прислали лишнее — до обработчика оно не доедет. Если хочется именно 400, это уже настраивается через Ajv.

Бонусом — скорость

Под капотом сериализация ответа идёт не через JSON.stringify, а через fast-json-stringify: на старте по response-схеме компилируется специализированная функция, и дальше она работает в разы быстрее (в бенчах самой библиотеки — до 2x на типовых ответах). JSON.stringify каждый раз обходит объект на ходу и не знает заранее, какие поля в нём окажутся. fast-json-stringify знает структуру и идёт почти прямым проходом по известным полям. Платим за это одной компиляцией на старте — копейки.

Дока Fastify.

Резюме

— schema-first даёт один источник правды — декларацию данных, из которой вытекают валидация, сериализация и типы;
— code-first проще на старте, но копии одной правды быстро расходятся, и это всегда вылазит больно;
— в Fastify это работает из коробки, плюс бонусом сериализация в разы быстрее обычного JSON.stringify.
Fastify Validation and Serialization — Fastify latest Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture.
  • 🔥 21
  • ❤ 3
  • 👍 3
  • 🍌 2
More from @temaprog
  1. Sep 15, 2026Здарова, работяги! Кто собирается на Avito.Tech.Conf 26 сентября? Я уже рассказывал про ко…
  2. Sep 14, 2026Зачем ты пишешь? Здарова, работяги! Помню, как все только начинали активно использовать аг…
  3. Sep 4, 2026Здарова, работяги! Приезжает коробка. Внутри бейдж на Avito.Tech.Conf и часы «Ракета».😳 И…
  4. Sep 3, 2026Здарова, работяги! Потихоньку продолжаю дописывать посты из заметок. В прошлый раз — элеме…
  5. Aug 26, 2026Здарова, работяги! Совсем скоро осень, а значит, начинается сезон конференций. Про Avito.T…
  6. Aug 18, 2026Здарова, работяги! Сейчас я много думаю про AI-native команды и внедрение ИИ в разработку.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →