Маппинг REST API и БД: как связаны JSON и таблицы
При работе с REST API часто возникает вопрос: обязательно ли каждое поле в JSON-ответе соответствует полю в таблице базы данных? Многие разработчики, особенно начинающие, сталкиваются с несоответствием данных, которые возвращает API, и структурой таблиц в БД. Давайте разберёмся, что скрывается за фразой «сущность отгружается полностью» и как устроен реальный маппинг.
Что значит «сущность отгружается полностью» в REST API
В REST-архитектуре под сущностью понимается логический объект предметной области, а не запись в базе. Например, сущность «Пользователь» может содержать поля: id, name, email, createdAt. Когда говорят «сущность отгружается полностью», это означает, что API возвращает все атрибуты, необходимые клиенту для работы с этим объектом. Однако это не равно всем полям таблицы в БД.
На практике REST-сущность - это проекция (DTO - Data Transfer Object), которая может включать:
- Расчётные поля (например, возраст, вычисляемый из даты рождения);
- Агрегированные данные (количество заказов пользователя);
- Поля из связанных таблиц (название города вместо ID).
Таким образом, прямой маппинг «один ключ JSON = одно поле таблицы» - это частный случай, а не обязательное правило.
Почему не все поля JSON маппятся на таблицы БД
Существует несколько причин, по которым поля в REST-ответе могут не совпадать со столбцами в БД:
- Безопасность: скрываются служебные поля (например, пароль, хэш, внутренние ID).
- Производительность: часть данных может храниться в кэше или вычисляться на лету.
- Абстракция: API может предоставлять упрощённую версию сущности, чтобы не раскрывать сложную структуру БД.
Например, в таблице может быть поле is_deleted (1/0), а в JSON - status: 'active'. Маппинг есть, но он косвенный.
Как работают POST/PUT/PATCH запросы: обновление сущности vs таблицы
Здесь важно различать два уровня:
- PUT - обновляет сущность целиком. Клиент передаёт все поля сущности (даже те, которые не изменились). Сервер принимает этот JSON и заменяет всю запись в БД (или все поля в таблице).
- PATCH - частичное обновление. Передаются только изменяемые поля. Сервер обновляет только указанные столбцы.
- POST - создание новой сущности. Переданные поля маппятся на соответствующие столбцы, но могут добавляться автоматические поля (например,
created_at).
Важно: PUT не обязательно обновляет все таблицы, к которым относится сущность. Он обновляет только те поля, которые входят в DTO. Если в JSON не передаётся поле internal_note, оно не изменится (если только в логике сервера не предусмотрено иное).
Как защитить структуру БД от утечки через API
Чтобы злоумышленник не мог по JSON-ответу восстановить схему таблиц, следуют практикам:
- Использовать DTO (Data Transfer Objects) - отдельные классы для передачи данных, не совпадающие с моделями БД.
- Применять маппинг через AutoMapper или аналоги - преобразование полей с изменением имён и типов.
- Не возвращать внутренние идентификаторы (например,
user_idв таблице) там, где достаточно публичногоuuid. - Исключать служебные поля (
version,created_by,updated_at), если они не нужны клиенту.
Таким образом, REST API - это не зеркало БД, а специально сформированный слой, который решает задачи интерфейса, безопасности и производительности.
Практический совет: как разобраться в маппинге без программирования
Если вы видите в Swagger поля, которых нет в таблице, или наоборот - в таблице есть столбцы, отсутствующие в JSON, это нормально. Чтобы понять логику:
- Изучите код сервисного слоя (если есть доступ) - именно там происходит преобразование.
- Спросите у разработчиков, какие DTO используются для данного эндпоинта.
- Попробуйте написать простой тестовый REST API на Node.js или Python (даже без глубоких знаний) - это быстро прояснит картину.
Главное - запомните: сущность в REST - это логический объект, а не запись в базе. Маппинг полей может быть как прямым, так и косвенным, а количество полей в JSON и таблице почти всегда различается.