Encodera

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

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

Оглавление

Проверка данных по схеме

Клиент может прислать что угодно: пустой заголовок, число вместо текста, лишние поля. Fastify проверяет входящие данные по схеме — описанию в формате JSON Schema (стандарт, где структура данных задаётся обычным объектом). Если данные не подходят, обработчик даже не вызывается, а клиент получает ошибку 400.

Схема тела запроса

Схему передают вторым аргументом маршрута в опции schema. В src/routes/posts.js:

// src/routes/posts.js
const createPostSchema = {
  body: {
    type: 'object',
    required: ['title', 'body'],
    properties: {
      title: { type: 'string', minLength: 3, maxLength: 120 },
      body: { type: 'string', minLength: 1 },
    },
  },
};
 
app.post('/posts', { schema: createPostSchema }, async (request, reply) => {
  const post = { id: posts.length + 1, ...request.body };
  posts.push(post);
  return reply.code(201).send(post);
});

Схема требует два строковых поля: title от 3 до 120 символов и непустой body.

Что получит клиент

Отправьте статью без текста:

curl -X POST http://localhost:3000/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Привет"}'

Сервер ответит кодом 400:

{
  "statusCode": 400,
  "code": "FST_ERR_VALIDATION",
  "error": "Bad Request",
  "message": "body must have required property 'body'"
}

Запрос с обоими полями пройдёт и вернёт новую статью с кодом 201.

Параметры и query

Те же правила работают для params и querystring (так называется схема строки запроса):

// src/routes/posts.js
const listSchema = {
  querystring: {
    type: 'object',
    properties: {
      limit: { type: 'integer', minimum: 1, maximum: 50, default: 10 },
    },
  },
};
 
const showSchema = {
  params: {
    type: 'object',
    properties: {
      id: { type: 'integer' },
    },
  },
};
 
app.get('/posts', { schema: listSchema }, async (request) => {
  return posts.slice(0, request.query.limit);
});
 
app.get('/posts/:id', { schema: showSchema }, async (request) => {
  return posts.find((post) => post.id === request.params.id);
});

Fastify сам переводит строки в числа по типу integer, поэтому Number() больше не нужен. default: 10 подставляется, если limit не передан, а адрес /posts/abc вернёт ошибку 400.

Основные ключевые слова

КлючПримерСмысл
type'string', 'integer', 'object'Тип значения
required['title']Обязательные поля
minLength, maxLength3Длина строки
minimum, maximum1Границы числа
enum['draft', 'published']Допустимые значения
format'email'Формат строки
default10Значение по умолчанию

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

В Fastify 5 схема должна быть полной. Старая сокращённая запись без type: 'object' и properties больше не поддерживается: сервер либо не запустится, либо проверка просто не сработает:

// src/routes/posts.js
// Неправильно в Fastify 5:
const schema = { querystring: { limit: { type: 'integer' } } };

Всегда пишите type: 'object' и перечисляйте поля в properties.

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

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