Ситуация
Я работаю над спецификацией OpenAPI v3 для существующей кодовой базы. Подход основан на принципе ядра в контексте jaxrs (jersey). API должен будет поддерживать граф, состоящий из вершин (объектов со свойствами) и ребер (связывание вершин, возможно, имеющих свойства). Для json (де) сериализации мы полагаемся на Джексона.
Модель (связанная с графиками) выглядит примерно так:
Vertex:
type: object
...
properties:
id:
type: string
...
Edge:
type: object
...
properties:
start:
$ref: '#/components/schemas/Vertex'
destination:
$ref: '#/components/schemas/Vertex'
Проблемы / проблемы
Есть две проблемы:
- Накладные расходы : эта схема (и как мы ее используем) приведет к тому, что вершины будут повторяться в начале и поля назначения ребер. Это ненужная полезная нагрузка, которая может быть значительной для больших вершин (возможно, свойств / больших значений) и многих ребер, ссылающихся на эти вершины.
- Корректность : более серьезная проблема заключается в том, что может быть неясно, какие вершина - правильная вершина. Т.е. в запросе / ответе могут встречаться несколько экземпляров Vertex с одинаковым идентификатором, но с разными значениями. Это кажется подверженным ошибкам.
Направления решения
На стороне API мы можем использовать @JsonIdentityInfo и @JsonIdentityReference для решения этих проблем. Однако кажется невозможным генерировать клиентов, которые работают с этим.
Я думаю, что главная проблема здесь заключается в отсутствии поддержки со схемой спецификации OpenAPI / JSON для поддержки ссылок на объекты.
В моих «попытках Google» воды сильно запятнаны содержанием вокруг ссылок в самих схемах OAS / JSON ... go figure.
Я искал JSON Ссылка и Javascript Граф объектов , но я не нашел никаких зацепок для включения этих идей в схему OAS.
Ссылка на модель в виде строки
Наиболее вероятный маршрут для меня - смоделировать начальные и конечные свойства Edge
как string
s. Это, по крайней мере, решает проблемы выше. Это поднимает новую проблему: клиенты, сгенерированные swagger, менее интуитивно понятны в использовании:
new Edge()
.start(vertexA.getId())
.destination(vertexB.getId())
вместо
new Edge()
.start(vertexA)
.destination(vertexB)
Проблема хуже даже при чтении ответов:
Vertex start = graph.getVertices().stream()
.filter(v -> v.getId().equals(edge.getStart()))
.findFirst();
Vertex destination = graph.getVertices().stream()
.filter(v -> v.getId().equals(edge.getDestination()))
.findFirst();
вместо
Vertex start = edge.getStart();
Vertex destination = edge.getDestination();
Еще хуже то, что API будет иметь иерархию классов как для Vertex
, так и Edge
. При использовании string
в качестве типа для свойств начала и назначения безопасность типов в клиенте истощается.
Справка
Кто-нибудь имеет опыт работы с этим тип схемы? Любой совет, как смоделировать схему и / или поддержку в клиентских генераторах?