Розробка веб-бекенду на Node.js (Fastify)
Fastify вибирають не за хайпом—вибирають, коли пропускна спроможність має значення. Фреймворк обробляє до 76 000 запитів на секунду на одному ядрі в синтетичних тестах, це різниця відчувається в реальних проектах з high-frequency API: price-feed, real-time аналітика, публічні API з непередбачуваним трафіком.
Архітектура й організація коду
Fastify побудований навколо концепції плагінів—кожен плагін ізольований контекст зі своїми декораторами, хуками, обробниками:
// plugins/db.js
import fp from 'fastify-plugin'
import { Pool } from 'pg'
async function dbPlugin(fastify, opts) {
const pool = new Pool({ connectionString: opts.connectionString })
fastify.decorate('db', pool)
fastify.addHook('onClose', async () => pool.end())
}
export default fp(dbPlugin, { name: 'db' })
Роут зі схемою й валідацією
// routes/products/index.js
export default async function productsRoutes(fastify) {
fastify.get('/', {
schema: {
querystring: {
limit: { type: 'integer', minimum: 1, maximum: 100 },
offset: { type: 'integer', minimum: 0 }
},
response: {
200: { type: 'array', items: { $ref: 'Product#' } }
}
}
}, async (request, reply) => {
const { limit, offset } = request.query
return await fastify.db.query('SELECT * FROM products LIMIT $1 OFFSET $2', [limit, offset])
})
}
Схема маршруту—не документація, це входова валідація й серіалізація відповіді одночасно. Fastify використовує ajv для валідації й fast-json-stringify для серіалізації. Відповідь серіалізується в 2–5 разів швидше ніж JSON.stringify.
Аутентифікація з JWT
fastify.decorate('authenticate', async function(request, reply) {
try {
await request.jwtVerify()
} catch (err) {
reply.send(err)
}
})
fastify.get('/profile', {
onRequest: [fastify.authenticate]
}, async (request) => {
return request.user
})
Ролеве дозвіл через preHandler хук:
const requireRole = (role) => async (request, reply) => {
if (request.user.role !== role) {
return reply.code(403).send({ error: 'Forbidden' })
}
}
fastify.delete('/users/:id', {
onRequest: [fastify.authenticate],
preHandler: [requireRole('admin')]
}, handler)
База даних: вибір ORM
| Інструмент | Коли використовувати |
|---|---|
pg + type-safe wrapper |
Повний контроль SQL, критична продуктивність |
Drizzle ORM |
Type-safe SQL без overhead Prisma |
Prisma |
Швидкий старт, auto types, команда знає |
Knex |
Query builder, без ORM overhead |
Drizzle оптимальний для нових Node.js 18+ проектів:
import { pgTable, serial, varchar } from 'drizzle-orm/pg-core'
import { drizzle } from 'drizzle-orm/node-postgres'
const users = pgTable('users', {
id: serial('id').primaryKey(),
email: varchar('email').notNull().unique()
})
const result = await db.select().from(users).where(eq(users.email, email))
Кешування з Redis
fastify.register(fastifyRedis, { url: process.env.REDIS_URL })
fastify.get('/catalog', async (request, reply) => {
const cacheKey = `catalog:${JSON.stringify(request.query)}`
const cached = await fastify.redis.get(cacheKey)
if (cached) {
reply.header('X-Cache', 'HIT')
return JSON.parse(cached)
}
const data = await fetchCatalog(request.query)
await fastify.redis.setex(cacheKey, 300, JSON.stringify(data))
return data
})
Підтримка WebSocket
fastify.register(fastifyWs)
fastify.get('/ws/notifications', { websocket: true }, (socket, req) => {
socket.on('message', (raw) => {
const msg = JSON.parse(raw.toString())
})
const interval = setInterval(() => {
if (socket.readyState === socket.OPEN) {
socket.send(JSON.stringify({ type: 'ping' }))
}
}, 30000)
socket.on('close', () => clearInterval(interval))
})
Метрики для Prometheus
fastify.register(fastifyMetrics, {
endpoint: '/metrics',
defaultMetrics: { enabled: true }
})
Структуроване логування через pino—найшвидший Node.js логгер.
Таймлайн розробки
Типовий REST API для сайту/веб-додатку на Fastify:
- Проектування API (OpenAPI/Swagger)—3–5 днів: endpoint'и, схеми, аутентифікація
- Базовий каркас: плагіни, роути, міграції—3–5 днів
- Бізнес-логіка—залежить від складності; 1–2 тижні для CRUD-сайту, 3–6 тижнів для складного додатку
- Інтеграції (платіж, email, зовнішні API)—1–3 тижні
- Тести + документація—3–7 днів
Для простого корпоративного сайту з API (каталог, форми, кабінет)—повний цикл 4–8 тижнів. Fastify перевага: валідація й документація пишуться раз у схемі маршруту—економить час на обслуговуванні.







