How to give a swagger parameter default value? - spring

I want somes params on swagger have its own default value. Is there anyway to give a default value ?
like this
this note has to be filled automatically with "stackoverflow"

You have to annotate your note parameter with defaultValue="stackoverflow".
You method signature should look like this:
public ResponseEntity<?> yourMethod(#ApiParam(value = "Default value for note", required = true, defaultValue = "stackoverflow") #Valid #RequestParam final String note) { }

Related

Hidden parameter in springdoc-openapi doesn't work

I have Spring Boot application with version 2.3.0.
and springdoc-openapi-webflux-ui in version 1.4.1.
I have annotated parameter in operation like this.
parameters = {
#Parameter(
hidden = true, schema = #Schema(implementation = Boolean.class),
in = ParameterIn.QUERY, name = DO_NOT_FORWARD
)
With hidden = true I expected that this parameter will not be visible in swagger-ui. But it is.
Did I misunderstood this parameter or is it not doing what it was supposed to do?
I want this parameter to be in api-docs, to have generated client able to use this parameter, but I want it invisible in swagger-ui
Try
#Parameter(name = "paramName", hidden = true)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
instead of
#Operation(
parameters = {
#Parameter(name = "paramName", hidden = true)
}
)
#GetMapping("/example")
public Object example(String paramName) {
return null;
}
You just make sure that the name of in the #Parameter annotation, is the exact name of the operation parameter you want to hide.
You can have a look at the documentation as well:
https://springdoc.org/faq.html#how-can-i-hide-a-parameter-from-the-documentation-
If you are still having coniguration issue, you can add the code of sample HelloController that reproduces your problem, or you can add the link to a minimal, reproducible sample in github.
As per the doc
#GetMapping("/example")
fun someCall: Response (
#Parameter(hidden = true) String paramName
) {
return response;
}

Springboot controller request param for map always null

I'm trying to pass in a bunch of id's to create a filter.
The incoming request looks like (ignoring the pagination stuff, which works fine)
http://localhost:8080/news-items?filter%5B%5D=09c731de-7ed8-385d-849c-f4d6535137ab&filter%5B%5D=dd1ba187-2df9-3985-ad1c-a4cde2dfe669&modelPath=controller.newsItems&page=0&per_page=25
Where the filter param equals an ID, but there is a bunch of them, for example:
filter: [
"09c731de-7ed8-385d-849c-f4d6535137ab",
"dd1ba187-2df9-3985-ad1c-a4cde2dfe669"
],
I can't seem to collect the filters in the controller. At the moment I have
public String getFeeds(#RequestParam(value = "filter", required = false) MultiValueMap<String, String> filter, #RequestParam(value = "page", required = false) int page, #RequestParam(value = "per_page", required = false) int perPage) {
log.info("Filter: {}", filter);
}
However filter is always null. I've tried using a String rather than a map but that is also always null.
How do I go about accepting an unknown number of params in this manner? I get the feeling this is really simple but I'm just missing the obvious...
Turns out it was simple like I thought. When using a Map in the #RequestParam it takes all the incoming params, regardless of what they are.
So from what I can tell the correct solution is to do something like
#GetMapping(produces = APPLICATION_JSON)
public String getFeeds(#RequestParam MultiValueMap<String, String> params) {
params.forEach(//something);
}
I think what you are looking for is just an Array or a List, something like below :
public String getFeeds(#RequestParam(value = "filter", required = false) List<String> filters) { ... }

Automatically adding #ImplicitParams with specific type of method argument of Spring Controller

Previously, I had Spring controller as below.
#RequestMapping(method = GET)
public List<TheResponse> getResponses(
#RequestParam(defaultValue = "1") int offset,
#RequestParam(defaultValue = "10") int limit) {
Pagination pagination = new Pagination(offset, limit);
...
return someResponse;
}
Swagger was generating document of this method with correct parameters information.
Later I created PaginationArgResolver by implementing HandlerMethodArgumentResolver. After that, I have to update the method as below, and apply #ApiImplicitParams to make it work with Swagger.
#ApiImplicitParams({
#ApiImplicitParam(name = "offset", dataType = "int", defaultValue = "1"),
#ApiImplicitParam(name = "limit", dataType = "int", defaultValue = "10")
})
#RequestMapping(method = GET)
public List<TheResponse> getResponses(#ApiIgnore Pagination pagination) {
...
}
Is there anyway #ImplicitParams is applied automatically whenever Pagination type argument is found?
OR
If I expose #PaginationSupported annotation, can I process it to achieve same results?
I am currently using springfox v2.4.0.
PS. I can edit source of Pagination class, in case some swagger annotation is needed there.
Why adding #ApiIgnore springfox will resolve these attributes inside the class automatically. When you want to add default values and other stuff you can add the #ApiParam annotation to the class attributes as well.
class Pagination {
#ApiParam(defaultValue = "1")
private int offset;
// [..]
}

Using #RequestParam annotated method with swagger ui

I am using Springfox libraries to generate documentation for REST service and display it in Swagger UI. I followed the directions in Springfox documentation.
I have one controller, which uses parameters from query string and the method is mapped as following:
#ApiOperation(value = "")
#RequestMapping(method = GET, value = "/customcollection/{id}/data")
public Iterable<CustomeType> getData(#ApiParam(value = "The identifier of the time series.")
#PathVariable String id,
#ApiParam(name = "startDate", value = "start date", defaultValue = "")
#RequestParam("startDate") String startDate,
#ApiParam(name = "endDate", value = "end date", defaultValue = "")
#RequestParam("endDate") String endDate)
The resulting mapper in swagger-ui then displayed as:
GET /customcollection/{id}/data{?startDate,endDate}
Parameters are displayed correctly in the UI:
But when I click on Try it Out, the request URL is misformed:
http://localhost:8080/customcollection/1/data{?startDate,endDate}?startDate=1&endDate=2
How can it be fixed?
This was caused by the line
enableUrlTemplating(true)
in Docket configuration which I copied from example and forgot to remove.
After removing this line everything is working as expected.

Spring Matrix Variables require at least one template variable to work?

I've been trying to get a simple REST API to list contents of a collection and I'm using matrix variables to control the pagination.
My controller has the following method to list contents of a collection:
#RequestMapping(
value = "articles",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody ArticlePageRestApiResponse listArticles(
#MatrixVariable(required = true, defaultValue = 100, value = "resultsPerPage") int resultsPerPage,
#MatrixVariable(required = true, defaultValue = 0, value = "pageNumber") int pageNumber) {
// some logic to return the collection
}
If I then do a GET http://example.com/articles;resultsPerPage=22;pageNumber=33 it fails to find a request mapping. I have enabled matrix variables support by adding the following:
#Configuration
public class EnableUriMatrixVariableSupport extends WebMvcConfigurationSupport {
#Override
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping hm = super.requestMappingHandlerMapping();
hm.setRemoveSemicolonContent(false);
return hm;
}
}
What I've found is that if the matrix variables are prefixed with at least one template variable then the matrix variables are correctly assigned. The following works but is ugly where I've had to make part of the URI path a template variable that is always going to be "articles" to trick the Request Mapping Handler into thinking there is at least one URI template variable :
#RequestMapping(
value = "{articles}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody ArticlePageRestApiResponse listArticles(
#PathVariable("articles") String ignore,
#MatrixVariable(required = true, defaultValue = 100, value = "resultsPerPage") int resultsPerPage,
#MatrixVariable(required = true, defaultValue = 0, value = "pageNumber") int pageNumber) {
// some logic to return the collection
}
Have I found a bug or am I mis-understanding matrix variables?
According to Spring documentation
If a URL is expected to contain matrix variables, the request mapping
pattern must represent them with a URI template. This ensures the
request can be matched correctly regardless of whether matrix
variables are present or not and in what order they are provided.
In your first example you use no templates (like {articles}) in URL mapping, so Spring is unable to detect matrix parameters.
I'd rather call it not a bug, but an implemnetation side effect. We have it just because #MatrixVariable support is build on the top of the old #PathVariable parsing mechanism.

Resources