swagger客户端中的对象图

时间:2020-04-26 10:22:08

标签: openapi swagger-codegen

情况

我正在为现有代码库制定OpenAPI v3规范。该方法基于jaxrs(球衣)上下文中的swagger-core。 API将需要支持由顶点(具有属性的实体)和边(链接顶点,可能具有属性)组成的图形。对于json(反)序列化,我们依赖杰克逊。

模型(与图形有关)类似于:

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

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

问题/挑战

有两个问题:

  • 开销:这种模式(以及我们的使用方式)将导致顶点在边的起始和目标字段中重复。这是不必要的有效负载,对于较大的顶点(可能是属性/较大的值)以及许多引用这些顶点的边来说可能是相当大的。
  • 正确性:一个更严重的问题是,可能不清楚哪个顶点是正确的顶点。即请求/响应中可能会有多个具有相同ID但值不同的Vertex实例。这似乎容易出错。

解决方案的方向

在API方面,我们可以使用@JsonIdentityInfo和@JsonIdentityReference解决这些问题。但是,似乎不可能生成与此相关的客户端。

我想这里的主要问题是缺乏OpenAPI规范/ JSON模式对对象引用的支持。

在我的“ Google努力”中,OAS / JSON模式本身中的引用周围的内容使很多事情变得混乱不堪。

我一直在研究JSON ReferenceJavascript Object Graph,但没有发现将这些想法纳入OAS架构的秘诀。

模型参考为字符串

对我而言,最可能采用的方法是将Edge的开始和目标属性建模为string。至少解决了以上问题。这确实带来了一个新问题:由摇摇欲坠生成的客户端使用起来不太直观:

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将同时具有VertexEdge的类层次结构。在将string用作开始和目标属性的类型时,客户端中的类型安全性将一the不振。

帮助

有人对这种模式有经验吗?关于如何在客户端生成器中对架构和/或支持进行建模的任何建议?

1 个答案:

答案 0 :(得分:0)

我正在经历完全相同的情况,尤其是在Google搜索方面:JSON模式参考命中率很高,它们都与复杂的对象图序列化无关。

我在服务器端(java)所做的事情:我有自己的对象序列化程序,它足够聪明,可以处理对象引用。每个对象都有一个ID。首次序列化对象时,序列化程序的输出是对象JSON表示形式。当对象再次出现在图中时,序列化程序仅输出带有#objectid的对象引用。

例如:

    {
    "created": "05/03/2020 17:49:08",
    "name": "Object Group [5109]",
    "objectID": 5109,
    "elements": [
        {
            "created": "05/03/2020 17:49:08",
            "name": "Element [5110]",
            "description": "Object example [5109]",
            "objectID": 5110
            "parent": #5109
        },
       ...
    ]
}

当然,如果要在客户端正确表示对象图,则必须在JavaScript代码中反序列化,并在反序列化期间设置客户端对象引用。我不知道在openapi生成的客户端中有什么机制。