Currently I have API which have something like below
#GetMapping("/list/{type}")
#ApiOperation(nickname = "reportUnits", httpMethod = "GET", produces = "application/json", responseContainer = "List", response = ReportFormatDTO.class, value = "Returns all available report Units", notes = "Returns all available report Units", consumes = "text")
#ApiResponses({ #ApiResponse(code = 404, message = "No data found"),
#ApiResponse(code = 500, message = "Error getting Report Units"), })
Flux<ReportFormatDTO> getList(#PathVariable("type") String type);
I need to tell swagger about fixed set of String to be passed in the Path variable.
Related
I have the following Swagger configuration
#Bean
#RouterOperation(path = PEOPLE_SEARCH_URL, produces = {MediaType.APPLICATION_JSON_VALUE},
beanClass = PersonSearchHandler.class, method = RequestMethod.GET, beanMethod = "getSearchResponse",
operation = #Operation(operationId = "getSearchResponse", security = {#SecurityRequirement(name = "Bearer Authentication")},
responses = {
#ApiResponse(responseCode = "200", description = "Successful operation",
content = #Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = #Schema(implementation = SearchResponse.class))
)},
parameters = {#Parameter(in = ParameterIn.QUERY, name = "request",
description = "SearchRequest object in JSON format converted to base64",
schema = #Schema(implementation = SearchRequest.class))}
))
My endpoint receives serialised SearchRequest object, which is encoded with Base64.
On swagger-ui I put encoded string , not Json object
The problem is - when I try to pass request param encoded with Base64 from Swagger UI, it validates this string against schema implementation = SearchRequest.class. But just remove #Schema is not an option, since I need to have request example and possibility to pass base64 encoded string.
So , I looking for work around and find some options:
Remove #Schema and just add 'example' to #Parameter. But SearchRequest consists a lot fields, so it is expanded to a lot of lines and look very bad.
In some way, if it possible, disable validation against schema , so I can just put encoded string in request param.
I will be very grateful for any workarounds and advices.
So I am trying to make a HTTP request to get access token and refresh token using following java code.
String url = "https://oauth2.googleapis.com/token?";
Map<String, String> parameters = new HashMap<>();
parameters.put("code", "4%2******");
parameters.put("client_id", "*****");
parameters.put("client_secret", "*****");
parameters.put("redirect_uri", "http://localhost");
parameters.put("grant_type","authorization_code");
parameters.put("access_type","offline");
String form = parameters.keySet().stream()
.map(key -> key + "=" + URLEncoder.encode(parameters.get(key), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url))
.headers("Content-Type", "application/json")
.POST(BodyPublishers.ofString(form)).build();
HttpResponse<?> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode() + response.body().toString());
But using this code gives the following error,
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unexpected token.\ncode=4%2****\n^",
"status": "INVALID_ARGUMENT"
}
}
What is the mistake that I have done here and should rectify in order to get proper results?
You are sending application/x-www-form-urlencoded data format but according to the response message you should send json. Try to change definition of form:
String form = new ObjectMapper().writeValueAsString(parameters);
I am new to writing integration tests. I must write code to check if my get method returns code 200. The problem is that this method is very complicated. I use 3 APIs to make it run.
Below I leave code of test method:
#Test
#WithUserDetails("operator")
public void getAnalysesByTagId_shouldReturn200() throws Exception {
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
MvcResult mvcResult = mockMvc.perform(multipart("/documents")
.file(getMetaDataFile("fileForAnalysisAndTags" + new Random().nextInt() + ".xlsx")))
.andExpect(status().isCreated()).andReturn();
DocumentCreateResponse document = parseResponse(mvcResult, DocumentCreateResponse.class);
MvcResult mvcDocumentDetails = mockMvc.perform(get("/documents/" + document.getId() + "/details")).andReturn();
DocumentDetailsResponse documentDetailsResponse = parseResponse(mvcDocumentDetails, DocumentDetailsResponse.class);
MvcResult mvcResultTag = mockMvc.perform(get("/tags/" + documentDetailsResponse.getAreaId() + "/children")).andReturn();
List<TagResponse> tagResponses = parseResponseList(mvcResultTag, TagResponse.class);
mockMvc.perform(get(TAGS_API + 1 + ANALYSES_API)).andExpect(status().isOk());
}
It returns code 404 instead of 200, I do something wrong in last line. I also leave the code of method thats being tested:
#GetMapping("tags/{tagId}/analyses")
#ApiOperation(value = "Find analyses associated with tag", produces = MediaType.APPLICATION_JSON_VALUE, notes = "Required Role: OPERATOR/USER")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Analyses found"),
#ApiResponse(code = 404, message = "Not found, incorrect tag ID"),
#ApiResponse(code = 500, message = "Server error, something went wrong"),
#ApiResponse(code = 401, message = "Request lacks valid authentication credentials.")
})
public ResponseEntity<List<FindAnalysisResponse>> getAnalysesByTagId(
#PathVariable("tagId") Long tagId) throws NotFoundException {
var analyses = service.getAnalysesByTagId(tagId)
.stream()
.map(findAnalysisMapper::fromAnalysis)
.collect(Collectors.toList());
return new ResponseEntity<>(analyses, HttpStatus.OK);
}
In logs I can see, that only last lines are generating error:
Async:
Async started = false
Async result = null
Resolved Exception:
Type = com.name.common.domain.NotFoundException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"text/plain;charset=UTF-8", Content-Length:"15", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = text/plain;charset=UTF-8
Body = "Tag not found"
Forwarded URL = null
Redirected URL = null
Cookies = []
What should I do to make it work?
May be there is no tag 1 present?
mockMvc.perform(get(TAGS_API + 1 + ANALYSES_API)).andExpect(status().isOk());
I have a specific DTO I'm using to return as an example for Swagger documentation. How can I change the example in case I have a success 201 code?
Example responses in swagger:
I use the annotations "#ApiModelProperty" to describe my objects, but finding no way on how to change the example for different response codes. In my code, I don't want to show the Errors list, as it's an optional property and it will just be available when non 201 codes are going to be produced.
Ideas?
You can do this with a couple of annotations as follows:
import io.swagger.v3.oas.annotations.media.ExampleObject;
#Operation(summary = "Your summary")
#ApiResponses(value = {
#ApiResponse(responseCode = "200", description = "Your description",
content = { #Content(mediaType = "application/json",
schema = #Schema(implementation = YourModel.class),
examples = [#ExampleObject(value = "{\"timestamp\": 1581552186590, \"status\": 404, \"error\": \"Not Found\", \"message\": \"Error message\", \"requestId\": \"62bcf95d\"}")]) })})
We try using swagger 2.0 (OAS3) for the documentation of a Restful API, implemented in Java and based on Apache CXF (jaxrs).
For a handful API-Calls yet implemented, the documentation with swagger works fine, but the following Post-Request makes me struggling:
#POST
#Path("/documents")
#Consumes("multipart/mixed")
Response createDocument(
#RequestBody(description = "RestDocumentParams (required), InputStream and RelationshipParams",
content = { #Content(mediaType = "multipart/mixed", schema = #Schema(implementation = RestDocumentParams.class)),
#Content(mediaType = "application/octet-stream", schema = #Schema(type = "string", format = "binary")),
#Content(mediaType = "application/json", schema = #Schema(implementation = RelationshipParams.class)) })
#Multipart(value = "doc", type = MediaType.APPLICATION_JSON)
RestDocumentParams documentParams,
#Multipart(value = "file", type = MediaType.APPLICATION_OCTET_STREAM, required = false)
InputStream inputStream,
#Multipart(value = "rela", type = MediaType.APPLICATION_JSON, required = false)
RelationshipParams relationshipParams)
This method should create a new Document using at least the data given in RestDocumentParams. Optionaly a file object (InputStream) and additional
MetaData (RelationshipParams) can be provided. All this payload has to be provided in the RequestBody.
Using this method in a testframework (e.g. restassured) works fine.
My problem is, how I have to annotate this method correct with swagger-annotation, to use it in Swagger-UI.
Using the RequestBody-Annotation like above, seems not being the right way!
In Swagger-UI appears a combo-box within the description of the RequestBody and let me choose the three different media types.
But if I want to try out this method and edited one of the input parameters (e.g. entering a file name) and choose the next media type, the last editing is lost.
Comparing the json-Strukture of the requestBody for this method with the OAS3 definition for "multipart content" differ.
Regarding to the OAS3 definition, the requestBody should have look like this:
requestBody:
description: 'RestDocumentParams (required), InputStream and RelationshipParams'
content:
multipart/form-data:
schema:
properties:
docParams:
$ref: '#/components/schemas/RestDocumentParams'
relaParams:
$ref: '#/components/schemas/RelationshipParams'
fileName:
type: string
format: binary
But I don't know how I have to specify the requestBody (using swagger annotoations) to achive a structure which looks like this.