Skip to content

Make it possible to mark parameters with @RequestParam annotation to be sent in form instead of query. #2826

New issue

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

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

Already on GitHub? # to your account

Closed
kkochanski opened this issue Dec 19, 2024 · 2 comments

Comments

@kkochanski
Copy link

I'm using.

  • Spring Boot v3.4.0
  • Springdoc OpenAPI v2.7.0

The @RequestParam annotation is tricky. Spring Boot will scan query and form to pass data to annotated variable.

@PostMapping(path = "/process", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(value = HttpStatus.OK)
public String process(
    @Boolean @RequestParam(name = "is_dummy", defaultValue = "false") String isDummy,
    @Min(10) @RequestParam(name = "age") int age
) {
    return "";
}

For this definition, doing a cURL or request from generated API Docs will not work.

cURL

curl -X 'POST' \
  'http://localhost:8080/process?is_dummy=false&age=11' \
  -H 'accept: application/json' \
  -d ''

Few issues here.

  1. Spring Boot will return org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type is not supported exception.
  2. We got a POST so technically speaking parameters should be send in form instead of query.
  3. In endpoint definition there's a mention that it consumes Form Url Encoded, but still Swagger do not setup a content-type.

Instead, cURL should like below.

curl -X 'POST' \
  'http://localhost:8080/process' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'age=11&is_dummy=false'

It's possible to fix given code by removing consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE. So we got.

@PostMapping(path = "/process", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ResponseStatus(value = HttpStatus.OK)
public String process(
    @Boolean @RequestParam(name = "is_dummy", defaultValue = "false") String isDummy,
    @Min(10) @RequestParam(name = "age") int age
) {
    return "";
}

Then cURL works. Although I still we'd love to have a possibility to tell users to send a data in form instead of query.

@kkochanski
Copy link
Author

@bnasslahsen Thanks a lot for your changes.

I noticed that after your changes, for annotation below, the proper Swagger docs are generated:

@PostMapping(path = "/dummy", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)

Although for another ones below, not (it's still as it was before - params are added to query instead of form).

@PostMapping(path = "/dummy", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)

I think we should send parameters via form whether the endpoints consumes multipart or form urlencoded.

Thanks!

@bnasslahsen
Copy link
Collaborator

@kkochanski,

For MediaType.MULTIPART_FORM_DATA_VALUE, there can be multiple options and you can use

springdoc.default-support-form-data=true

And if you are having another issue, make sure you provide the full description of the minimal sample with the expected results.

ndwlocatieservices added a commit to ndwnu/nls-accessibility-map that referenced this issue Jan 14, 2025
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [nu.ndw.nls.locationdataissuesapi:client-feign](https://dev.azure.com/ndwnu/NLS/_git/nls-location-data-issues) ([source](https://dev.azure.com/ndwnu/NLS/_git/nls-location-data-issues)) | compile | patch | `1.0.17` -> `1.0.18` |
| [org.springdoc:springdoc-openapi-starter-webmvc-ui](https://springdoc.org/) ([source](https://github.com/springdoc/springdoc-openapi)) | compile | minor | `2.7.0` -> `2.8.0` |

---

### Release Notes

<details>
<summary>springdoc/springdoc-openapi (org.springdoc:springdoc-openapi-starter-webmvc-ui)</summary>

### [`v2.8.0`](https://github.com/springdoc/springdoc-openapi/blob/HEAD/CHANGELOG.md#280---2025-01-03)

[Compare Source](springdoc/springdoc-openapi@v2.7.0...v2.8.0)

##### Added

-   [#&#8203;2790](springdoc/springdoc-openapi#2790) - Moving to OpenAPI 3.1 as the default implementation for springdoc-openapi
-   [#&#8203;2817](springdoc/springdoc-openapi#2817) - Obey annotations when flattening ParameterObject fields
-   [#&#8203;2826](springdoc/springdoc-openapi#2826) - Make it possible to mark parameters with [@&#8203;RequestParam](https://github.com/RequestParam) annotation to be sent in form instead of query.
-   [#&#8203;2822](springdoc/springdoc-openapi#2822) - Support returning null in ParameterCustomizer
-   [#&#8203;2830](springdoc/springdoc-openapi#2830) - Add support for deprecated fields.
-   [#&#8203;2780](springdoc/springdoc-openapi#2780) - Add Security Schema by AutoConfigure

##### Changed

-   Upgrade spring-boot to 3.4.1
-   Upgrade spring-cloud-function to 4.2.0
-   Upgrade swagger-core to 2.2.27

##### Fixed

-   [#&#8203;2804](springdoc/springdoc-openapi#2804) - Stable release 2.7.0 depends on Spring Cloud Milestone 4.2.0-M1
-   [#&#8203;2828](springdoc/springdoc-openapi#2828) - Required a bean of type 'org.springframework.data.rest.webmvc.mapping.Associations' that could not be found.
-   [#&#8203;2823](springdoc/springdoc-openapi#2823) - Capturing pattern in identical paths only renders the path element of one method
-   [#&#8203;2817](springdoc/springdoc-openapi#2817) - Automatically add required if a field is [@&#8203;notNull](https://github.com/notNull) or [@&#8203;NotBlank](https://github.com/NotBlank).
-   [#&#8203;2814](springdoc/springdoc-openapi#2814) - An unresolvable circular reference with management.endpoint.gateway.enabled=true.
-   [#&#8203;2798](springdoc/springdoc-openapi#2798) - Object schema generated for Unit Kotlin type.
-   [#&#8203;2797](springdoc/springdoc-openapi#2797) - Removing operationId via customizer does not w...
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants