Маппинг 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 и таблице почти всегда различается.

    Часто задаваемые вопросы