为什么在OpenAPI中有不同类型的组件?

huangapple go评论48阅读模式
英文:

Why are there different components types in OpenAPI?

问题

尝试理解OpenAPI中在components/schemas部分或components/requestBodies部分定义可重用对象之间的区别,如果它确实是请求体的对象,是否有除了分离不是真正领域对象的简单请求有效载荷之外的任何区别?为什么要为schemasrequestBodiesresponses拥有不同的部分?

特别是在查看生成的客户端代码时,我看不出在schemas中定义的类和在requestBodies中定义的类之间有什么区别。

英文:

Trying to wrap my head around OpenAPI difference between defining a reusable object in the components/schemas section or in the components/requestBodies if it's indeed an object that is the body of a request.

Is there any difference besides the separation of simple request payloads that are no real domain objects? Why do we have different sections for schemas, requestBodies, and responses?

Especially when looking at the generated client code I see no difference between a class that was defined in schemas or one defined in requestBodies.

答案1

得分: 5

A schema(模式)描述了API使用的特定数据结构,例如某个对象、其属性、它们的数据类型等等。

一些其他组件类型使用模式作为它们的构建块之一。

请求正文(request body)组件定义了请求正文是必需还是可选的,支持的请求正文媒体类型(例如 application/jsonmultipart/form-dataapplication/octet-stream)以及每种媒体类型的模式(这些模式可以相同也可以不同)。

类似地,响应(response)组件不仅定义了响应模式,还定义了可能的响应媒体类型和响应头部。

如果我们将指定的部分重写为 components,那么可以得到以下内容:

paths:
  /users:
    post:
      summary: 创建用户
      requestBody:
        $ref: '#/components/requestBodies/createUser'
      responses:
        '201':
          $ref: '#/components/responses/userCreated'

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          example: Helen
  
  requestBodies:
    createUser:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/User'
        application/x-www-form-urlencoded:
          schema:
            $ref: '#/components/schemas/User'
  
  responses:
    userCreated:
      description: >-
        用户已成功创建。
        响应包含已创建的用户。        
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/User'

尽管使用 components/schemas 为模式命名是一种常见做法,但使用 components/requestBodiescomponents/responses 而不是内联定义更多是一种便利的做法。通常,只有在相同的请求正文定义或响应定义在多个地方重复使用时,才会将其放入 components 中。例如,401和403响应通常在所有操作中具有相同的模式和描述,因此您可能希望使用 $ref 来减少重复,而需要唯一描述的200/201响应可以保持内联。

尤其是在查看生成的客户端代码时,我看不出在 schemas 中定义的类与在 requestBodies 中定义的类之间有任何区别。

这可能会因代码生成工具而异。但这可能是因为模式会转换为类,而请求正文和响应属性(如媒体类型)则使用注释表示。因此,在代码生成环境中,请求正文和响应是内联定义还是在 components 中定义通常并不重要。

英文:

A schema describes a specific data structure used by an API. Such as a certain object, its properties, their data types, and so on.

Some other component types use schemas as one of their building blocks.

A request body component defines whether the request body is required or optional, the supported media types for the request body (e.g. application/json, multipart/form-data, application/octet-stream) and the schema for each media type (these schemas can be the same or different).

Similarly, a response component defines not just the response schema, but also possible response media types and response headers.

为什么在OpenAPI中有不同类型的组件?

If we rewrite the indicated parts as components, we end up with:

paths:
  /users:
    post:
      summary: Create a user
      requestBody:
        $ref: '#/components/requestBodies/createUser'
      responses:
        '201':
          $ref: '#/components/responses/userCreated'

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          example: Helen
  
  requestBodies:
    createUser:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/User'
        application/x-www-form-urlencoded:
          schema:
            $ref: '#/components/schemas/User'
  
  responses:
    userCreated:
      description: >-
        The user was successfully created.
        The response contains the created user.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/User'

<br/>

While using components/schemas to give names to schemas is a common practice, using components/requestBodies and components/responses instead of inline definitions is more of a convenience thing. You would typically put the latter into components only if the same request body definition or response definition is duplicated in multiple places. For example, 401 and 403 responses usually have the same schema and description in all operations so you may want to $ref them to reduce the repetition, whereas 200/201 responses that need unique descriptions can be kept inline.

<br/>

> Especially when looking at the generated client code I see no difference between a class that was defined in schemas or one defined in requestBodies.

This might vary from one codegen to another. But it's probably because schemas are converted to classes, whereas request body and response attributes (such as media types) are expressed with annotations. So in the code generation context, it doesn't really matter if request bodies and responses are defined inline or in components.

huangapple
  • 本文由 发表于 2023年2月16日 02:42:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定