我什么时候应该使用 $ref 而不是 Open API 中的对象 ID

When should I use $ref versus the object id in Open API

我正在使用 Swagger 在 OpenAPI 中处理架构,我不确定我是否滥用了 $ref 元素。我有一个 User 模型和一个 Project 模型,类似于

User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        ...
Project:
      type: object
      properties:
        id:
          type: string
        user_id:
          $ref: "#/components/schemas/User"
        ...

我在 Open API 规范文档中没有看到很多关于 $ref 元素具体是什么的信息,但是在 JSON 架构文档中,其中 Open API 扩展了 $ref 元素——我找到了该项目的以下描述:

The easiest way to describe $ref is that it gets logically replaced with the thing that it points to.

在上面的例子中,我只想指代发布项目的用户。如果它正在做的话,似乎没有必要在项目模型中基本上包含所有关于用户的信息。只使用 user_id 的 uuid 的 string 元素会更好吗?或者它是正确的吗?如果是这种情况,将字段命名为 user 而不是 user_id 更常见吗?

编辑: 我意识到困扰我的核心是是否存在递归引用。如果一个用户对项目有一个 $ref 的数组,而且一个项目对用户有一个 $ref 的数组,则替换(如果这是它正在做的)将无限地将每个模型嵌入到另一个模型中。我认为这在实践中不会发生,假设 $ref 只是指向模型的指针?

在您的示例中,将 userId 定义提取到它自己的模式中可能是有意义的(假设它只是 userId 出现,而​​不是整个 User 对象),那么事情就更清楚了:

components:
  schemas:
    User:
      type: object
      properties:
        id:
          $ref: '#/components/schemas/userId'
        name:
          type: string
        ...
    Project:
      type: object
      properties:
        id:
          type: string
        user_id:
          $ref: "#/components/schemas/userId"
        ...
    userId:
      type: string
      format: uuid

但是没有什么可以阻止您创建直接 $ref#/components/schemas/User/properties/id,只要指向的是有效的 OpenAPI schemaObject。

JSON 参考和 OpenAPI 规范允许循环引用,因此您对指针的类比是合理的。