Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

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

Swagger UI - Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

问题

I am using Swagger/OpenAPI version: OpenAPI 3.0.3

示例Swagger/OpenAPI定义:

openapi: 3.0.3
info:
    title: 'My API'
    version: 3.0.0
servers: []
paths:
    /api_app:
        post:
            operationId: apiAppCreate
            requestBody:
                content:
                    multipart/form-data:
                        schema:
                            $ref: '#/components/schemas/ApiAppCreateRequest'
            responses:
                '200':
                    description: 'success'
                    content:
                        application/json:
                            schema: {}
components:
    schemas:
        ApiAppCreateRequest:
            properties:
                oauth:
                  type: object
                  properties:
                      callback_url:
                          type: string
                          example: 'https://example.com/oauth'
                      scopes:
                          type: array
                          items:
                              type: string
                          example:
                              - basic_account_info
                              - request_signature
            type: object

嵌套对象以Json输入形式显示,而不是如附图所示的form-data。

Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

只有当请求的类型为form-data或multipart/form-data并且包含嵌套对象时,才会发生此情况。

似乎在Swagger UI的GitHub问题中没有解决方案,所以想在StackOverflow上询问,看看是否有人能解决这个问题。

我使用Java 8,并且依赖如下:

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.7.0</version>
</dependency>

另一个例子,UI部分呈现为form-data,部分呈现为json输入。

Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

英文:

I am using Swagger/OpenAPI version: OpenAPI 3.0.3

Example Swagger/OpenAPI definition:

openapi: 3.0.3
info:
    title: &#39;My API&#39;
    version: 3.0.0
servers: []
paths:
    /api_app:
        post:
            operationId: apiAppCreate
            requestBody:
                content:
                    multipart/form-data:
                        schema:
                            $ref: &#39;#/components/schemas/ApiAppCreateRequest&#39;
            responses:
                &#39;200&#39;:
                    description: &#39;success&#39;
                    content:
                        application/json:
                            schema: {}
components:
    schemas:
        ApiAppCreateRequest:
            properties:
                oauth:
                  type: object
                  properties:
                      callback_url:
                          type: string
                          example: &#39;https://example.com/oauth&#39;
                      scopes:
                          type: array
                          items:
                              type: string
                          example:
                              - basic_account_info
                              - request_signature
            type: object

The nested object displays as Json input instead of form-data as shown in attached image.

Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

It should be rendered as form-fields. This happens only when we have form-data or multipart/form-data type of request and it has a nested object within.

Seems no solution on github issues of swagger ui so thought of asking on stackoverflow if in case anyone able to resolve this issue.

I am using Java 8 with dependency:

&lt;!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springdoc&lt;/groupId&gt;
    &lt;artifactId&gt;springdoc-openapi-ui&lt;/artifactId&gt;
    &lt;version&gt;1.7.0&lt;/version&gt;
&lt;/dependency&gt;

Another example of how the UI renders partly in form-data and partly as json input

Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

答案1

得分: 1

问题
我不确定oauth到底是用作什么,但似乎这是一个请求oauth令牌的请求。您面临的问题是由于您的模式声明,您将所有内容声明为oauth的属性。type: object将所有内容强制转换为JSON模式,并通过将所有内容声明为oauth的属性,将其强制转换为JSON对象的oauth模式。

properties:
  oauth:
    type: object
    properties:

您可以通过两种方式修复此问题。

解决方案1
删除顶级属性值,并减小callback_urlscopes的缩进。

components:
  schemas:
    ApiAppCreateRequest:
      properties:
        oath:
          type: object
        callback_url:
          type: string
          example: 'https://example.com/oauth'
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object

这将导致在"试一试"中显示如下内容
Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

解决方案2
完全删除oauth

components:
  schemas:
    ApiAppCreateRequest:
      properties:
        callback_url:
          type: string
          example: 'https://example.com/oauth'
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object

这将完全删除oauth的JSON对象,如下截图所示。
Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

备选方案
根据您对oauth属性的具体用途,您还可以重新构造属性,例如将其作为文件或安全模式:

作为文件
将其视为文件,只需更新模式以具有type: stringformat: binary。这将允许用户上传文件以用作安全授权。

oauth:
  type: string
  format: binary

作为安全模式
您还可以将oauth作为请求的一部分单独包括在安全模式中。

openapi: 3.0.3
info:
    title: 'My API'
    version: 3.0.0
servers: []
paths:
  /api_app:
    post:
      operationId: apiAppCreate
      requestBody:
          content:
            multipart/form-data:
              schema:
                  $ref: '#/components/schemas/ApiAppCreateRequest'
      security:
        - oAuthSample:
          - create_app
      responses:
        '200':
          description: 'success'
          content:
            application/json:
              schema: {}
components:
  schemas:
    ApiAppCreateRequest:
      properties:
        callback_url:
          type: string
          example: 'https://example.com/oauth'
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object
  securitySchemes:
    oAuthSample:
      type: oauth2
      description: This API uses OAuth 2 with the implicit grant flow. [More info](https://whatever.com)
      flows:
        implicit:
          authorizationUrl: https://whatever.com
          scopes:
            create_app: create a new app

最后
multipart/form-data内容类型有很多可能性。您可以查看swagger文档openapi文档以获取更多信息。例如,您可以使用encoding属性来控制请求正文的各个部分的序列化方式。这包括设置标头、explodestyle

英文:

Problem

I'm not sure what exactly oauth is being used as, but it seems like this is a request for an oauth token. The issue you are facing is due to your schema declaration, where you are declaring everything as a property of oauth. The type: object forces everything into a json schema, and by declaring everything as a property of oauth, it's forcing it into the oauth schema as a json object.

properties:
  oauth:
    type: object
    properties:

You can fix this two ways.

Solution 1

remove the top level properties value and reduce the indentation of the callback_url and scopes.

components:
  schemas:
    ApiAppCreateRequest:
      properties:
        oath:
          type: object
        callback_url:
          type: string
          example: &#39;https://example.com/oauth&#39;
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object

This will result in the following display in your try it out
Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

Solution 2

Remove the oauth entirely.

components:
  schemas:
    ApiAppCreateRequest:
      properties:
        callback_url:
          type: string
          example: &#39;https://example.com/oauth&#39;
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object

This will remove the json object for oauth completely, as the below screenshot demonstrates.
Swagger UI – Rendering nested object in multipart/form-data request "try it out" shows JSON instead of form UI fields

Alternatives

Depending on what you are trying to do with the oauth property, you could also restructure what the property is, such as a file or a security schema:

As a file

As a file, simply update the schema to have a type: string and format: binary. This will allow the user to upload a file to be used as the security authorization.

oauth:
  type: string
  format: binary

As security schema

You can also include the oauth as the security schema separately as a part of the request.

openapi: 3.0.3
info:
    title: &#39;My API&#39;
    version: 3.0.0
servers: []
paths:
  /api_app:
    post:
      operationId: apiAppCreate
      requestBody:
          content:
            multipart/form-data:
              schema:
                  $ref: &#39;#/components/schemas/ApiAppCreateRequest&#39;
      security:
        - oAuthSample:
          - create_app
      responses:
        &#39;200&#39;:
          description: &#39;success&#39;
          content:
            application/json:
              schema: {}
components:
  schemas:
    ApiAppCreateRequest:
      properties:
        callback_url:
          type: string
          example: &#39;https://example.com/oauth&#39;
        scopes:
          type: array
          items:
            type: string
          example:
            - basic_account_info
            - request_signature
      type: object
  securitySchemes:
    oAuthSample:
      type: oauth2
      description: This API uses OAuth 2 with the implicit grant flow. [More info](https://whatever.com)
      flows:
        implicit:
          authorizationUrl: https://whatever.com
          scopes:
            create_app: create a new app

Finally

The multipart/form-data content type has a lot of possibilities. You can check the swagger documentation or the openapi documentation for more information. For example, you can use the encoding property to gain control over the way in which various parts of the request bodies are serialized. This includes setting the headers, explode, and style.

huangapple
  • 本文由 发表于 2023年5月21日 01:00:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76296380.html
匿名

发表评论

匿名网友

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

确定