Reputation: 323
My API-first swagger client/server transfers POST request body parameter object incorrectly. Spring (4.3.14.RELEASE) server receives nulls in the @RequestBody parameter of the POST request.
The key difference between requests passed over SwaggerUI and over generated typescript client is that SwaggerUI passes object fields as query parameters (Spring handles well), but the generated typescript client over json body (Spring handles nulls).
It seems like autogenerated client sends parameter over body, but the autogenerated server expects parameters in the query.
The swagger fragment:
/project:
post:
security:
- Bearer: []
tags:
- Project
summary: Create new project
operationId: createProject
consumes:
- "application/json"
- "text/json"
parameters:
- name: project
in: body
description: project value
schema:
$ref: '#/definitions/ProjectRequestDTO'
responses:
'200':
description: Successful response
schema:
$ref: '#/definitions/ProjectDTO'
default:
description: Bad requst
The resulting Spring MVC method:
ApiOperation(value = "Create new project", nickname = "createHachathon", notes = "", response = ProjectDTO.class, authorizations = {
@Authorization(value = "Bearer")
}, tags={ "Project", })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successful response", response = ProjectDTO.class),
@ApiResponse(code = 200, message = "Bad requst") })
@RequestMapping(value = "/project",
consumes = { "application/json", "text/json" },
method = RequestMethod.POST)
default ResponseEntity<ProjectDTO> createHachathon(@ApiParam(value = "project value" ) @Valid @RequestBody ProjectRequestDTO project) {
I'm sending request from typescript over manually hacked client (title parameter added as demonstration that this parameter will be unmarshalled well):
return this.httpClient.post<ProjectDTO>(`${this.basePath}/project?title=hello`,
The resulting request in the Chrome console:
Unfortunatelly Spring receives only the value which were passed over query parameter but not over request body:
Plese help me to make my swagger-codegen-maven-plugin 2.3.1 produce client/server swagger API which will transfer data transparently.
Upvotes: 4
Views: 4140
Reputation: 13
Sometimes, it seems stupid but I had issue with my request body, it was null into the controller. What I changed, the import, I was using the swagger.requestBody
package instead of the springframeWork.request
import.
Upvotes: -1
Reputation: 320
Sorry, may be late answer. maybe helps someone. I was hitting same issue while using spring boot+Swagger2. My REST API with POST method :
public void getAllNames(@ApiParam(name = "Get All names Request",
value = "Request to get all names",
required = true) @RequestBody BasicCredentialsJsonObject requestJson)
I had to introduce Json annotations(JsonPropertyOrder
, JsonProperty
) on below class to get going. I was hitting issue till I made this changes.
BasicCredentialsJsonObject :
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"password",
"username"
})
public class BasicCredentialsJsonObject {
@JsonProperty("username")
private String username;
@JsonProperty("password")
private String password;
}
Upvotes: 0
Reputation: 323
The root cause is that Spring ignores method parameter annotations of the implemented Interface, so the @RequestBody was ignored in my Controller implementation.
The <delegatePattern>true</delegatePattern>
parameter inside <configOptions>
section of swagger-codegen-maven-plugin resolved this problem.
This parameter makes Swagger generate invocation of delegate method inside default implementation of API Interface methods. My Controller implements this method and overrides this delegate mathods, so the source method annotations are in safe.
Upvotes: 3