(попросили, я сделаль)
Все мы понимаем, что в API можно передавать данные в разных форматах: json, xml, текст, protobuf — суть не в этом. Важно то, что это структурированные данные, а значит, у них должна быть структура. Только вот пример — это не структура. Это иллюстрация. А нужен контракт.
Разберёмся на простом кейсе.
Допустим, у нас есть ручка POST /product, через которую создаётся товар. Пример тела запроса в JSON:
{
"product_id": "PRD-00123",
"name": "Ноутбук ASUS ZenBook 14",
"category": "Электроника",
"unit": "шт",
"price": 98000.00,
"currency": "RUB"
}
Выглядит красиво. Но это просто пример. Иногда рядом пишут:
- product_id: строка по шаблону PRD-00123
- unit: строка, значения типа шт
- price: число
...и всё.
📉 Что дальше?
- Бэкенд как-то валидирует (или не валидирует).
- Клиент делает UI на глаз (или убивает вас вопросами).
- Валидация происходит как получится.
📍 А если делать по уму?
Даже в позитивном сценарии на бэкенде у нас есть этапы:
1. Получить JSON и сериализовать (привести типы данных)
2. Проверить обязательные поля
3. Проверить типы и форматы данных на нужные нам для записи в базу
4. Проверить бизнес-логику (вдруг id не уникальный)
5. Сохранить в базу
6. Вернуть ответ
Проблема в том, что тестировать пример нельзя. А значит, валидировать нечего. А значит — ошибки на проде.
👨💻 Окей, у нас клиентская форма и мы хотим давать пользователю ввести ерунду.
Что мы поняли из документации:
- Типы данных есть
- Частично есть списки значений
А чего нет:
- Маска product_id. Можно PRD-ABC99?
- Макс. длина name, category? Нам что делать бесконечный input?
- Можно ли отрицательную цену? Точка или запятая в цене? Сколько знаков после запятой?
- Валюта: только RUB, или и BYN?
- Какие поля вообще обязательны?
📬 А если такое сообщение пришло по очереди из внешней системы?
Те же вопросы.
Как проектировать базу и писать обработку, если данные “примерно такие”? На ощупь?
-----Тут есть важный момент, не пытайтесь собирать особенности работы словами, записывайте хотя бы за всеми, а то потом скажут, что это не они-----
🎯 Вот тут и нужен контракт
Контракт — это не "пример". Это договорённость:
что, в каком формате, какие ограничения, и как это обрабатывать.
Вот примерчик в Openapi
components:
schemas:
Product:
type: object
required: [product_id, name, unit, price, currency]
properties:
product_id:
type: string
pattern: "^PRD-\\d{5}$"
example: "PRD-00123"
name:
type: string
maxLength: 200
example: "Ноутбук ASUS ZenBook 14"
category:
type: string
maxLength: 200
example: "Электроника"
unit:
type: string
enum: ["шт", "кг", "л", "м"]
example: "шт"
price:
type: number
minimum: 0.01
example: 98000.00
currency:
type: string
enum: ["RUB", "USD", "EUR"]
example: "RUB"
📊 Или старая добрая табличка:
- Атрибут
- Обязательность
- Тип данных
- Регулярка
- Допустимые значения
- Пример
- Особенности (например, уникальность)
🧘 Вывод
Всегда пытайтесь лучше описать реальность, поставить рамки, даже искусственные. Они вас уберегут. Давайте не пример, а контракт - договор, по которому вы собираетесь формировать и получать сообщения. Буть то внешний (сервер, очередь, другой бэк и др) или внутренный клиент (фронтовые приложения).
Контракт нужен, чтобы:
- Системы друг друга понимали
- Разработчики не гадали
- А валидаторы не ловили баги на проде
p.s. Cейчас кто-то вспомнит про json schema и xsd, ваше право, но для json мне больше нравится Openapi
#api@analyst_exe
analyst.exe | чат