swagger-api / swagger-ui

Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
https://swagger.io
Apache License 2.0
26.48k stars 8.95k forks source link

multipart/form-data should support custom content-type selection. #6462

Open mathis-m opened 4 years ago

mathis-m commented 4 years ago

Content & configuration

Swagger/OpenAPI definition:

paths:
  /analysis/api/stores:
    post:
      responses:
        '201':
          $ref: '#/components/responses/CONTINUE'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Child'
            encoding: # The same level as schema
              test: # Property name (see schema)
                contentType: application/json
              test2: # Property name (see schema)
                contentType: application/xml
      tags:
        - Learning
info:
  title: test api
  version: v1
tags:
  - name: Feature Request
    description: respect multipart child content-type
openapi: 3.0.2
components:
  schemas:
    Error:
      type: object
      properties:
        message:
          type: string
          description: Error message
        errors:
          type: object
          description: Errors
        status:
          type: string
          description: Error name
        code:
          type: integer
          format: int32
          description: Error code
    Base:
      type: object
      properties:
        company:
          type: string
    Child:
      type: object
      properties:
        test:
          type: array
          items:
            $ref: '#/components/schemas/Base'
        test2:
          type: array
          items:
            $ref: '#/components/schemas/Base'
  responses:
    CONTINUE:
      description: Continue
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string

Is your feature request related to a problem?

It is currently not possible to define specific Content-Type for a request part via encoding/{property-name}/contentType.

Describe the solution you'd like

Schema Property Type Content-Type
Primitive or array of primitives text/plain
Complex value or array of complex values application/json
String in the binary or base64 format application/octet-stream
sgrimm commented 3 years ago

Just ran into this with a file upload API that had an object part for some metadata. The whole proposed solution here would of course be great, but just setting the content types of the request parts based on the schema properties (that is, the last bullet point in the described solution) would be helpful even without any new elements in the UI.

To help anyone else who is searching the web for this problem: it was manifesting in Spring MVC as HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported. A workaround is to write a custom HttpMessageConverter to deserialize application/octet-stream bodies using Jackson.

hkosova commented 3 years ago

Related: #5356

rPraml commented 3 years ago

@sgrimm thanks, this workaround seems to work

    @Bean
    public MappingJackson2HttpMessageConverter octetStreamJsonConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Arrays.asList(new MediaType("application", "octet-stream")));
        return converter;
    }
little-pinecone commented 2 years ago

To expand on @rPraml's code, adding octet-stream to the supported media types in the existing MappingJackson2HttpMessageConverter will prevent bugs when using other media types:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.ArrayList;

@Configuration
public class SwaggerBeanConfig {

    public SwaggerBeanConfig(MappingJackson2HttpMessageConverter converter) {
        var supportedMediaTypes = new ArrayList<>(converter.getSupportedMediaTypes());
        supportedMediaTypes.add(new MediaType("application", "octet-stream"));
        converter.setSupportedMediaTypes(supportedMediaTypes);
    }
}
JanCizmar commented 5 months ago

+1