#java #android #json #rest
К примеру, есть модели: public class Shipment { private int id; private Destination destination private String status; } public class Destination { private int id; private String company; private String nameTo; } public class Order { private int id; private String reference; private Listshipments; } Есть JSON ответ чтобы получить Order: { "id": 78, "reference": "FD456", "shipments": [ { "id": 86160, "destination": 172002, "status": "ready" } } Есть JSON ответ чтобы получить Shipment: { "id": 86160, "destination": [ { "id": 172002, "company": "KLM inc", "name_to": "Alex" } "status": "ready" } Как видно в первом JSON поле destination хранит просто id, а во втором JSON приходит уже сам объект Destination. Как я понимаю это сделано в целях оптимизации, но вопрос состоит в том, как хранить такое различие типов в моделях?
Ответы
Ответ 1
Такое получилось из-за БД на стороне API С точки зрения API там два разных типа данных: сама модель и ссылка на модель. В самом общем смысле. "Голый id" это ссылка, по которой API может однозначно найти нужную запись. Скорее всего, это внешний ключ в какой-то SQL-базе. Если у вас, потребителя API, есть своя БД, то в ней это можно представить, как поле, хранящее ..._api_id (где ссылка) и api_id (где значение). Как внешний и первичный ключ (соотв-но), но поскольку в базе "снаружи", соответствующие значения есть не всегда. Если пришла ссылка, то сохранить только в это поле, если значение, то сделать строчку в другой таблице и заполнить это поле. А если базы нет, можно завести singleton-мапы id => объект и... дальше варианты. Если вы уверены, что эти объекты меняются редко, эти мапы можно использовать, как кэш. Например, получили вы id, и оказалось, что в мапе эта запись уже есть (ранее у API спрашивалась), можно её сразу и взять. А если считаете, что они меняются часто, то вам придётся делать ещё один запрос, чтобы точно получить самую свежую версию объекта. Можно совместить два подхода, и обновлять объект только если запрос был достаточно давно. Да-да, пресловутый "cache invalidation". Так или иначе, в объекте у вас будет только число — ключ для мапа. Если в мапе такого значения нет, его надо достать с API и записать в мап. Вам стоит поискать в этом API место, которое вам этот объект выдаст целиком. В приведённых JSON-ответах разработчики, вероятно, решили, что данные смежных объектов нужны часто и решили их вложить по значению, а не по ссылке.Ответ 2
Так а в чём сложность то? Проверяйте при сериализации/десериализации в json какие данные есть и в зависимости от этого или создавайте/меняйте destination, или просто прогружайте по id. Конфликта то с конечной моделью, в которой идёт ссылка на объёкт, а не его id то нету.Ответ 3
Не суть важно в чем причина такого ответа JSON от сервера. Я так понимаю ТС не контролирует что ему выдает сервер - иначе он бы изменил JSON ответ :) Теперь к сути вопроса: суть если кратко состоит в том, что объект Destination сериализуется иногда как полномасштабный объект, а иногда только как id - вопрос - как обрабатывать это на этапе десериализации (посколько сериализацию мы не контролируем, то остается только этап десериализации). Ответ: Модель оставляем такой как описано у вас. Далее берем Google GSON и пишем десериализатор, примерно так: public class MyDeSerializer implements JsonDeserializer
Комментариев нет:
Отправить комментарий