Какие инструменты используются для маппинга данных от сетевого слоя до слоя данных
Что проверяют
Понимаете ли вы, зачем разделять модели по слоям, и можете ли защитить приложение от сюрпризов бэкенда. Интервьюеру важно, чтобы сетевой ответ не протекал в UI как есть. Следом обычно спрашивают, где живут мапперы, как вы их тестируете и что будет, если сервер пришлёт null в обязательном поле.
Как отвечать
Разведите две задачи: разбор JSON и преобразование между слоями. Для разбора:
- Retrofit или Ktor Client: HTTP-клиент, Ktor выбирают под Kotlin Multiplatform;
- kotlinx.serialization:
@Serializable, код генерирует плагин компилятора, понимает nullability и значения по умолчанию. Для Retrofit есть официальный конвертер; - Moshi: с кодогенерацией через KSP тоже корректно работает с Kotlin;
- Gson: встречается в легаси, но про Kotlin ничего не знает.
Преобразование между слоями обычно пишется руками:
- DTO: класс ответа сервера, поля nullable или с дефолтами, живёт в data-слое;
- Entity: таблица Room с
@Entity, если есть кеш; - доменная модель: чистый Kotlin без аннотаций библиотек;
- мапперы: функции-расширения вроде
fun UserDto.toDomain(): User, покрытые unit-тестами. MapStruct в Kotlin-проектах редок: выигрыш небольшой, а работает он через kapt.
Для офлайн-режима Room становится единственным источником правды: сеть пишет в базу, UI подписан на Flow из DAO. С Paging 3 эту связку собирает RemoteMediator.
Где спотыкаются
Не знают, чем опасен Gson в Kotlin. Он умеет создавать объекты в обход конструктора, поэтому дефолтные значения не применяются, а поле типа String без знака вопроса спокойно оказывается null и падает уже в UI.
Забывают про ignoreUnknownKeys. По умолчанию kotlinx.serialization бросает исключение на незнакомое поле, и когда бэкенд добавит поле в ответ, старые версии приложения начнут падать. С новым значением enum то же самое, тут помогает coerceInputValues или свой сериализатор.
Используют один класс сразу как DTO, Entity и модель для UI. Любое изменение API тогда ломает базу и экраны одновременно, а миграция Room превращается в хирургию.