Skip to content

Multipart Request with JSON #820

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jposes22 opened this issue Aug 9, 2020 · 1 comment
Closed

Multipart Request with JSON #820

jposes22 opened this issue Aug 9, 2020 · 1 comment

Comments

@jposes22
Copy link

jposes22 commented Aug 9, 2020

Describe the bug

  • I try to make a simple request with multipart and JSON object but doesn't generate the right request.

An example of StackOverflow:
https://stackoverflow.com/a/25183266/4693765

To Reproduce
Steps to reproduce the behavior:

  • Spring boot 2.2.5.RELEASE
  • Spring doc 1.4.4
  • Kotlin project with:
springdoc-openapi-ui
springdoc-openapi-data-rest
springdoc-openapi-security
springdoc-openapi-kotlin

Rest controller:

 @PostMapping("test",consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
   fun saveDocu2ment(@RequestPart(value = "file",required = true) file: MultipartFile,
                     @RequestPart(required = true)  type:MailDto) {
    }

Open Api JSON

  "paths": {
    "/api/v2/mail/test": {
      "post": {
        "tags": [
          "mail-rest-controller-v-2"
        ],
        "operationId": "saveDocu2ment",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "type": {
                    "$ref": "#/components/schemas/MailDto"
                  }
                }

Request when execute with swagger-ui:
curl -X POST "http://localhost:8080/api/v2/mail/test" -H "accept: */*" -H "Content-Type: multipart/form-data" -F "type={ "authorizationToken": "string", "to": [ "string" ], "sender": "string", "subject": "string", "bodyText": "string", "files": [ "string" ] }" -F "file=@img_payment_success.png;type=image/png"

Screenshots
Image of example request
image

Additional context
An error response of spring boot (oviusly error):
ERROR 3108 --- [nio-8080-exec-1] e.d.s.base.BaseAdviceRestController : Content type 'application/octet-stream' not supported

@bnasslahsen
Copy link
Collaborator

@jposes22,

This is not a springdoc issue: springdoc-openapi is built on top of swagger-api/swagger-ui and spring-boot.
springdoc-openapi helps generating the OpenAPI spec. And you are not reporting any inconsitency about that.

The correct code, for your sample is:

@PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
@RequestBody(content = @Content(encoding = @Encoding(name = "personDTO", contentType = "application/json")))
public ResponseEntity<Void> saveDocu2ment(
		@RequestPart(value = "personDTO")  final PersonDTO personDTO,
		@RequestPart(value = "file")  final MultipartFile file) {
	return null;
}

Which produces the following OpenAPI description:

openapi: 3.0.1
info:
  title: OpenAPI definition
  version: v0
servers:
  - url: 'http://localhost:8080'
    description: Generated server url
paths:
  /test:
    post:
      tags:
        - hello-controller
      operationId: saveDocu2ment
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                personDTO:
                  $ref: '#/components/schemas/PersonDTO'
                file:
                  type: string
                  format: binary
            encoding:
              personDTO:
                contentType: application/json
      responses:
        '200':
          description: OK
components:
  schemas:
    PersonDTO:
      type: object
      properties:
        email:
          type: string
        firstName:
          type: string
        lastName:
          type: string

Unfortunately, swagger-ui doesn't handle yet the support of the encoding attribute.

As discussed here #396, there is a workaround is to use the type binary for the other parts: (swagger-ui scans for the file extension to add the type of the request part).

Here a working sample code: The first parameter content should be in a file (with .json extension)

@PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public ResponseEntity<Void> saveDocu2ment(
		@RequestPart(value = "personDTO") @Parameter(schema =@Schema(type = "string", format = "binary")) final PersonDTO personDTO,
		@RequestPart(value = "file")  final MultipartFile file) {
	return null;
}

@springdoc springdoc locked as resolved and limited conversation to collaborators Oct 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants