openapi-generator
openapi-generator copied to clipboard
[BUG][SPRING] Spring generator not creating query parameter objects with @ParameterObject annotation
Bug Report Checklist
- [x] Have you provided a full/minimal spec to reproduce the issue?
- [x] Have you validated the input using an OpenAPI validator (example)?
- [x] Have you tested with the latest master to confirm the issue still exists?
- [x] Have you searched for related issues/PRs?
- [x] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
If I generate spring code with springoc annotation provider from an OpenAPI spec where an operation is defined that contains an object as query parameter I expect this object being annotated with @ParameterObject or have a possibility to do so.
openapi-generator version
- openapi-generator-maven-plugin 6.0.0
- tried also with openapi-generator latest master and 7.0.x branch
OpenAPI declaration file content or url
openapi: 3.0.0
info:
title: Query object as @ParameterObject
version: '1.0'
servers:
- url: http://localhost:8080
tags:
- name: "Book"
paths:
/books:
get:
tags:
- "Book"
summary: Get all Books
operationId: getAllBooks
x-spring-paginated: true
parameters:
- name: BookFilter
in: query
schema:
type: object
properties:
name:
type: string
author:
type: string
responses:
'200':
description: A list of Books
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Book"
components:
schemas:
Book:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
author:
type: string
Generation Details
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \ -i above_file.yaml \ -g spring \ -o /generated-output
Steps to reproduce
- run generation with the command stated above
Output is:
/**
* GET /books : Get all Books
*
* @param bookFilter (optional)
* @return A list of Books (status code 200)
*/
@Operation(
operationId = "getAllBooks",
summary = "Get all Books",
tags = { "Book" },
responses = {
@ApiResponse(responseCode = "200", description = "A list of Books", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = Book.class))
})
}
)
@RequestMapping(
method = RequestMethod.GET,
value = "/books",
produces = { "application/json" }
)
default ResponseEntity<List<Book>> getAllBooks(
@Parameter(name = "BookFilter", description = "") @Valid GetAllBooksBookFilterParameter bookFilter,
@ParameterObject final Pageable pageable
) {
getRequest().ifPresent(request -> {
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString = "{ \"author\" : \"author\", \"name\" : \"name\", \"id\" : 0 }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
}
});
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
Related issues/PRs
Suggest a fix
I suggest annotating the request parameter object with ParameterObject instead of Parameter like this:
/**
* GET /books : Get all Books
*
* @param bookFilter (optional)
* @return A list of Books (status code 200)
*/
@Operation(
operationId = "getAllBooks",
summary = "Get all Books",
tags = { "Book" },
responses = {
@ApiResponse(responseCode = "200", description = "A list of Books", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = Book.class))
})
}
)
@RequestMapping(
method = RequestMethod.GET,
value = "/books",
produces = { "application/json" }
)
default ResponseEntity<List<Book>> getAllBooks(
@ParameterObject @Valid GetAllBooksBookFilterParameter bookFilter,
@ParameterObject final Pageable pageable
) {
getRequest().ifPresent(request -> {
for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString = "{ \"author\" : \"author\", \"name\" : \"name\", \"id\" : 0 }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
}
});
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
Would appreciate if someone could make a suggestion to make this possible or comment with any concerns about this.
Workaround: annotate the method parameter in implementation
@Overrride
public ResponseEntity<List<Book>> getAllBooks(@ParameterObject GetAllBooksBookFilterParameter bookFilter, @ParameterObject Pageable pageable) {