How to specify request body in Spring boot for swagger UI? - java

I have the following annotated controller for swagger:
#PostMapping("/getMediaDataProduct/V2")
#ResponseBody
#ApiOperation(value = "get media data product v2")
#ApiResponses({#ApiResponse(code = 200, message = "Successful", response = MediaDataProductResponseV2.class)})
#ApiImplicitParams(value = {
#ApiImplicitParam(name = "xxxxx", value = "xxxx", paramType = "header", required = true),
#ApiImplicitParam(name = "xxxx", value = "xxxx", paramType = "header", required = true),
#ApiImplicitParam(name = "xxxx", value = "xxxx", paramType = "header"),
#ApiImplicitParam(name = "xxxx", value = "xxxx", paramType = "header", required = true),
// #ApiImplicitParam(name = "xxxxxx", value = "xxx", paramType = "header" ,required = true),
#ApiImplicitParam(name = "xxxxxx", value = "xxxxx", paramType = "header"),
#ApiImplicitParam(name = "xxxxxxx", value = "xxxxxxxx", paramType = "header", required = true)})
public ResponseEntity getMediaDataProductV2(#RequestBody final String request, #RequestHeader final HttpHeaders headers) {
Slogger.get().debug("/getMediaDataProduct/V2: this.mediaDataService: " + this.mediaDataService);
MediaDataProductResponseV2 response = mediaDataService.getMediaDataProductV2(request);
HttpStatus status = getHttpStatus(response.getStatusMessages(), response.getSystemErrors());
List<StatusMessage> statusMessages = appendSuccessStatusMessage(response.getStatusMessages(), status);
if(statusMessages !=null) {
response.setStatusMessages(statusMessages);
}
return new ResponseEntity<>(response, new HttpHeaders(), status);
}
How can you specify the request body so it's displayed in the swagger UI?
update: I have tried to research on this in many forums but doesn't seem to find an answer. "How can you specify the request body class by using swagger annotations just as I do with ApiResponses?". There is a default parameter in swagger UI created for body but don't know how to specify it by referencing the request body class.

If I understood your problem correctly, you need to have a response type shown in the swagger definition. Most of the time Swagger will automatically map your method return type as response type.
But, it fails to do so when it's a generic class, as in your case its ResponseEntity.
If you can make your return type to something like ResponseEntity<MediaDataProductResponseV2>, it should work.

According to Swagger documentation, you can declare paramType attribute at #ApiImplicitParam only with the following values:
Valid values are path, query, body, header or form.
the Default is ""
In your case, try to do something like this.
#ApiImplicitParams(value = {
#ApiImplicitParam(name = "request", value = "The body is a simple string", paramType = "body", required = true),
#ApiImplicitParam(name = "headers", value = "It'll contain all header attributes in request", paramType = "header", required = true)})
public ResponseEntity getMediaDataProductV2(#RequestBody final String request, #RequestHeader final HttpHeaders headers) {
Slogger.get().debug("/getMediaDataProduct/V2: this.mediaDataService: " + this.mediaDataService);

Related

How to annotate Page<Foo> for generate correct response

RestController return response
Page<Foo>
I annotate like this
#ApiResponses(value = {
#ApiResponse(
responseCode = "200",
content = #Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
array = #ArraySchema(
schema = #Schema(implementation = Foo.class)
)),
description = "The request has succeeded")
but i need to generate page instead of array.
Is there any way to do this
if should be look like this
schema PageFoo->data-> [{Foo}]
if i remove annotation it will generate right schema but without content-type
#ApiResponses(value = {
#ApiResponse(
responseCode = "200",
content = #Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = #Schema(implementation = PageFoo.class)
),
description = "The request has succeeded"
)
})
class PageFoo {
#Schema(name = "data", implementation = Foo.class, type = SchemaType.ARRAY)
List<Foo> data;
//...
}

Working with SwaggerUI & JAX-RS - Adding a custom header globally

I was trying to inject a global header to my suite of requests. While studying the solution I found the annotation #ApiImplicitParam that has #Target(value=METHOD)
example:
#DeleteMapping(value = "/token/{version}", produces = "application/json; charset=UTF-8")
#ApiOperation(value = "delete actual token", produces = "application/json", response = Application.class)
#ApiImplicitParams(
{
#ApiImplicitParam(name = "My-custom-header", required = true, paramType = "header",
dataType = "string", value = "custom header", defaultValue = "GOOD")
}
)
public Application deleteAuthenticationToken(
#ApiParam(required = true, value = "version", defaultValue = "v1") #PathVariable("version") String version,
HttpServletRequest request) {
here the docs
https://docs.swagger.io/swagger-core/current/apidocs/io/swagger/annotations/ApiImplicitParam.html
This means that this annotation can't be set to the resource and being automatically applied to all the methods.
I need that every call has this custom header, is there a way of doing it globally?
EDIT1: I added a HeaderParam in the swagger config but it doesn't work
private void inizializeSwagger(){
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_API_VERSION));
beanConfig.setSchemes(PropertiesConfig.getConfig().getStringArray(PropertiesConst.P_SWAGGER_PROTOCOL));
beanConfig.setHost(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_HOST));
beanConfig.setResourcePackage(PropertiesConfig.getConfig().getString(PropertiesConst.P_SWAGGER_RESOURCES_PACKAGE));
Swagger swagger = new Swagger();
swagger.securityDefinition("basic", new BasicAuthDefinition());
Parameter globalOperationParameter = new HeaderParameter();
globalOperationParameter.setName("System");
globalOperationParameter.setRequired(Boolean.TRUE);
globalOperationParameter.setDescription("definition of the calling system");
swagger.parameter("System", globalOperationParameter);
new SwaggerContextService().updateSwagger(swagger);
beanConfig.setScan(true);
}
EDIT2:
It adds the parameters but SwaggerUI 2.0 doesn't show it
EDIT3:
I had to change the swaggerUI library implementation:
in the cycle of // operations (row 4695) I added the following
for(name in spec.parameters) {
var actualParam = spec.parameters[name];
if(actualParam.in === 'header') {
parameters.unshift({"name":actualParam.name,
"in":actualParam.in,
"description":actualParam.description,
"required":actualParam.required,
"type":"string",
"default":""})
}
}
In other words I added the params I needed in the cycling operation.
I leave this ticket opened for better and cleaner solutions

Swagger datatype not generating docs

I have the below code in Swagger,
#Path("/v1")
#ApiOperation(value = "POST - Some Value", nickname = "post-funtion", consumes = "application/json", produces = "text/html; charset=UTF-8", tags = {
"Some Controller" })
#ApiImplicitParams({
#ApiImplicitParam(name = "Authorization", paramType = "header", dataType = "string", format = "JWT", required = false, value = "A User Service JWT"),
#ApiImplicitParam(name = "Request", value = "Request Object", paramType = "body", dataType = "org.pkg.SomeRequest", required = true) })
#ApiResponses({
#ApiResponse(code = 200, message = "Value Added", response = SomeResponse.class) })
private Object retrieveByName(Request request, Response response)
{
return new RetrieveByNameRqstHandler(catalogService, request, response).handle();
}
The code is supposed to automatically generate default json request depending upon the datatype which in this case is "org.pkg.SomeRequest" but there is nothing generated. On the contrary if I change the "org.pkg.SomeRequest" with "org.pkg.SomeResponse" there is a default JSON generated for this. Can anybody help me please?
Consider both classes SomeRequest,SomeResponse have the same code.
This is the image where I use "org.pkg.SomeRequest" in the dataType
This is the image where I use "org.pkg.SomeResponse" in the dataType
According to this GitHub issue on Swagger core project, if you add the annotation #ApiImplicitParam should resolve your problem.
#ApiImplicitParams({
#ApiImplicitParam(
required = true,
dataType = "com.example.SomeObjectDto",
paramType = "body"
)
})
But normally if you just add the class on your method signature it'll work.
private Object retrieveByName(SomeObjectDto someObjectDto) {
someCode();
}
Also SomeObjectDto class should contain "get" methods for your variables like.
class SomeObjectDto {
private String info;
getInfo(){
return info;
}
}
Will produce the following JSon.
{ info: "string" }
ApiImplicitParam can map a parameter to a correct type, but the type must be detected by swagger, so must be a valid reference.
The only way I could make this working is by using additionalModels method.
Example in spring-boot:
configure swagger
import springfox.documentation.spring.web.plugins.Docket;
import com.fasterxml.classmate.TypeResolver;
...
#Bean
public Docket api(TypeResolver typeResolver) {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("your-group-rest-api")
.select()
.apis(RequestHandlerSelectors.basePackage("your.package"))
.paths(PathSelectors.any())
.build()
.additionalModels(typeResolver.resolve(YourModel.class))
.apiInfo(apiInfo());
}
controller
#ApiOperation...
#ApiImplicitParams(
#ApiImplicitParam(dataType = "YourModel", name = "requestJson", paramType = "body"))
#ApiResponses...
#RequestMapping...
public void yourMethod(#RequestBody String requestJson,...)
Of course, you could have an InputStream parameter for the request and map that to your model.

Swagger UI and Play routing *path

I'm having trouble with Swagger understanding Play! 2.0 routing wildcard routing, so the swagger ui ends up with broken URL.
My routes file has this route:
GET /settings/api/:project/*path #controllers.API.getParams(project, path)
Then my Controller has the following code:
#ApiOperation(value = "Returns settings for given project and path.", response = String.class, httpMethod = "GET")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Request completed successfully."),
#ApiResponse(code = 500, message = "Internal error while processing request")
})
#ApiImplicitParams({
#ApiImplicitParam(name = "project", value = "Project name", required = true, dataType = "String", paramType = "path"),
#ApiImplicitParam(name = "path", value = "path", required = true, dataType = "String", paramType = "path")
})
public Result getParams(String project, String path) {
return ok(path);
}
Then when Swagger UI gets rendered, I see the path for this action rendered as
POST /settings/api/{project}/{path<.+>
And when I do a call it turns into
/settings/api/test/{path<.+>
So basically the :project gets replaced but the *path remains broken/intact.
Please share if you know how to fix this. Thanks!
So turns out that swagger doesn't support wildcard routes.

Personnalize route format - Swagger with Play Framework

I am developing an API with Swagger UI using Play Framework.
But I got a little problem (not a big problem) :
My URL are :
https://url/find?param1=false&&&param4=1
But I have '&&' when a parameter is not given ( I mean param2 and param3)
What I want is simply :
https://url/find?param1=false&param4=1
Here is :
My Controller :
#Api(value = "url", description = "...")
public class nameClassApiController extends ApiController {
#ApiOperation(value = "...", notes = "...", response = nameClass.class, httpMethod = "GET")
#ApiResponses(value = { #ApiResponse(code = 200, message = "success"), #ApiResponse(code = 500, message = "error", response = ApiError.class) })
public static Result getList(
#ApiParam(value = "param1", required = false) #QueryParam("param1") Long param1,
#ApiParam(value = "param2", required = false) #QueryParam("param2") Long param2, ....) {
return getJsonSuccessResponse(className.getList(param1, param2, ...));
}
And my route definition :
GET url/find className.getList(param1: java.lang.Long ?= null, param2: java.lang.Long ?= null, param3: java.lang.Long ?= null, param4: java.lang.Long ?= null)
NB : Te parameters are optional so in my route I need to put the parameter by default to null.
Any solutions ?
Thank you !
Fixed by upgrading swagger-UI version to 2.0 (latest)

Categories

Resources