Forum Discussion

frensjan's avatar
frensjan
Visitor
4 years ago

Object graphs in swagger clients

Situation

I am working on an OpenAPI v3 specification for an existing codebase. The approach is based on swagger-core in a jaxrs (jersey) context. The API will need to support a graph consisting of vertices (entities with properties) and edges (linking vertices, possibly having properties). For json (de)serialisation, we're relying on jackson.

 

The model (related to graphs) is something like:

Vertex:
type: object
...
properties:
id:
type: string
...

Edge:
type: object
...
properties:
start:
$ref: '#/components/schemas/Vertex'
destination:
$ref: '#/components/schemas/Vertex'
...

Issues / challenges

There are two issues:

  • Overhead: This schema (and how we're using it) would result in vertices to be repeated in the start and destination fields of edges. This is unnecessary payload which may be considerable for large vertices (may properties / large values) and many edges referencing these vertices.
  • Correctness: A more serious issue is that it may be unclear which vertex is the correct vertex. I.e. multiple instances of Vertex may occur in a request / response with the same id, but with different values. This seems error prone.

Directions of solution

In the API side, we can use @JsonIdentityInfo and @JsonIdentityReference to resolve these issues. However, it seems impossible to generate clients that work with this.

 

I guess the main issue here is the lack of support from the OpenAPI specification / JSON schema to support object references.

 

In my "google endeavours" the waters are muddied a lot by content around references in OAS / JSON schema themselves ... go figure.

 

I've been looking into JSON Reference and Javascript Object Graph, but I have found no hooks to incorporate these ideas into an OAS schema.

 

Model reference as string

The most likely route to take for me is to model the start and destination properties of Edge as strings. That at least solves the issues above. This does bring up a new issue: clients generated by swagger are less intuitive to use:

new Edge()
   .start(vertexA.getId())
   .destination(vertexB.getId())

instead of

new Edge()
   .start(vertexA)
   .destination(vertexB)

The issue is worse even when reading responses:

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();

instead of

Vertex start = edge.getStart();
Vertex destination = edge.getDestination();

To make matters even worse still is that the API will have a class hierarchy for both Vertex and Edge. When using string as type for the start and destination properties, the type safety in the client is down the drain.

 

Help

Does anyone have experience with this type of schema? Any advice on how to model the schema and/or support in client generators?

No RepliesBe the first to reply