Как известно JSON пришёл из JavaScript, который является языком программирования с динамической типизацией и прототипной моделью данных. Грубо говоря там есть Object в который можно динамически добавлять всё что угодно - как поля, так и функции. В JavaScript вообще не нужно объявлять какую-то заранее известную дата модель. А вот в таких языках как Java, со статической типизацией, это делать надо. При этом возникает масса проблем.
Допустим у нас есть примерно следующая модель данных в Java:
public class Cage<T extends Animal> {
private T animal;
// boilerplate code omitted
}
Класс Animal является базовым классом и какой именно его потомок может оказаться в этом поле заранее не известно. Внутри JSON может прийти совершенно любое животное.
Может возникнуть необходимость держать в клетке несколько животных и даже допускать, что они будут разными. В этом случае потребуется их список.
public class Cage<T extends Animal> {
private List<T> animals;
// boilerplate code omitted
}
Проблема такого кода ещё и в том, что тип T всё равно статический и поселить, например, кошек с собаками в один список не получится, даже если они ладят друг с другом в реальной жизни.
Если данные приходят в виде JSON, их десериализация в такие модели данных со статической типизацией становится нетривиальной и это основная проблема, которую я хотел бы обсудить. Для того, чтобы всё работало правильно рано или поздно приходится добавлять в этот JSON дополнительную информацию о типах. В случае примеров выше - информацию о том, какой именно потомок Animal используется в каждом конкретном элементе списка. Мало того, что усложняется JSON, так ещё и десериализацию, например для REST контроллера в Spring Boot, приходится делать нестандартной.
Как правильнее решить эту проблему? Отказаться от POJO в пользу вложеных Map-ов или какого-то иного динамического отображения JSON (например ObjectNode из библиотеки Jackson)? Вообще отказаться от Java и писать серверный код на JavaScript под node.js? Или отказаться от JSON в пользу какого-то другого формата, у которого метаданные являются обязательными? На ум приходит что-то типа SOAP. Все три подхода имеют массу недостатков. Или может быть существует какой-то четвёртый подход, о котором я не подумал?