Reputation: 3540
I am developing a service-based application for which I am adding openapi
based annotations such as @RequestBody, @Parameter, @Schema
within the @Schema
I have an example
field for which I can provide the example template in String
format.
I have provided the example JSON string
but the JSON content is huge so I would like to add it from the file
present in my resources
folder. But I am currently unable to load it. Can someone please let me know how can I add the example content from the file rather than String?
I tried looking and found that there is a field externalValue
but I am unable to understand how to make it work. Following is the link to the documentation.
Following is the code I have which is working perfectly fine:
@Path("/generate")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequestBody(description = "InputTemplate body",
content = @Content(schema = @Schema(implementation = InputTemplate.class, example = "{\n" +
" \"names\":[\n" +
" \"Batman\",\n" +
" \"Superman\",\n" +
" \"Ironman\"\n" +
" ],\n" +
" \"jobs\":[\n" +
" \"Fighting\",\n" +
" \"Fyling\",\n" +
" \"Teching\"\n" +
" ]\n" +
"}")))
public Multi<String> generate(final Map<String, Object> input) throws CustomException {
}
I would like to replace the JSON contents present example
with the contents from the external file which is present in my resources
folder.
After trying many things I got to know that I need to use @ExampleObject
but if I add the respective annotations and try to open my Swagger UI
then I am not getting the contents of the file that I have added. Rather it provides me with the data from InputTemplate.class
.
Following is the modified code:
@RequestBody(description = "InputTemplate body",
content = @Content(schema = @Schema(implementation = InputTemplate.class), examples = {
@ExampleObject(name = "Example-1",
description = "Example-1 for InputTemplate.",
ref = "#/resources/Example1.json"), externalValue = "#/resources/Example2.json"
@ExampleObject(name = "Example-2",
description = "Example-2 for InputTemplate.",
ref = "#/resources/Example1.json") //externalValue = "#/resources/Example1.json"
}))
I tried to look into a similar question but the provided response does not work for me:
Upvotes: 9
Views: 5500
Reputation: 406
As best as I can tell, the ref value seems to be expecting a url where a schema could be found? I saw someone recommend making an endpoint to return examples? This seems a bit much to me...
I decided the easiest thing to do was just add something to pull examples from the files and insert them into the OpenApi object.
I implemented an OpenApiCustomiser
in my spring config, this allows me to point to files in the apps resources folder for Response examples.
I annotate the Controller method like this:
@ApiResponses(value = {
@ApiResponse(responseCode = "200",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = SomeResponse.class,
name = "YourResponse"),
examples = {@ExampleObject(value = "@your_data_200_response.json")}) })
})
To get the above to work you then add the following OpenApiCustomiser config bean:
@Bean
public OpenApiCustomiser applyStandardOpenAPIModifications() {
return openApi -> {
Paths paths = new Paths();
openApi.getPaths().entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(stringPathItemEntry -> {
paths.addPathItem(stringPathItemEntry.getKey(), addExamples(stringPathItemEntry.getValue()));
});
openApi.setPaths(paths);
};
}
private PathItem addExamples(PathItem pathItem) {
if(pathItem.getPost() !=null) {
//Note you can also Do this to APIResponses to insert info from a file into examples in say, a 200 response.
pathItem.getPost().getRequestBody().getContent().values().stream()
.forEach(c ->{
String fileName = c.getExample().toString().replaceFirst("@","");
ObjectNode node = null;
try {
//load file from where you want. also don't insert is as a string, it wont format properly
node = (ObjectNode) new ObjectMapper().readTree(methodToReadInFileToString(fileName));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
c.setExample(node);
}
);
}
return pathItem;
}
I just load the files from a folder places in /resources which contains the .json files.
Upvotes: 3