I am developing a Quarkus service-based application for which I am adding open API
based annotations such as @ExampleObject
. For this, I would like to add the resources file contents as an example that can appear in the SwaggerUI
.
I am getting the following error when I add the reference to the files from the resources folder:
Errors
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example1 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example1.json does not exist in document
Resolver error at paths./api/generateTestData.post.requestBody.content.application/json.examples.Example2 Schema.$ref
Could not resolve reference: Could not resolve pointer: /Example2.json does not exist in document
Following is my Quarkus based Java 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"
}))
Note:
I am able to add the String
as value
but the content for these examples is very large so I would like to read from the files only so trying this approach.
Is there any way I can access the resources file and add it as a ref
within my @ExampleObject
A working example below:
Create an OASModelFilter class which implements OASFilter
:
package org.acme;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.eclipse.microprofile.openapi.OASFactory;
import org.eclipse.microprofile.openapi.OASFilter;
import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.microprofile.openapi.models.examples.Example;
public class OASModelFilter implements OASFilter {
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void filterOpenAPI(OpenAPI openAPI) {
//openApi.getComponents() will result in NULL as we don't have any openapi.yaml file.
Components defaultComponents = OASFactory.createComponents();
if(openAPI.getComponents() == null){
openAPI.setComponents(defaultComponents);
}
generateExamples().forEach(openAPI.getComponents()::addExample);
}
Map<String, Example> generateExamples() {
Map<String, Example> examples = new LinkedHashMap<>();
try {
//loop over your Example JSON Files,..
//In this case, the example is only for 1 file.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream userJsonFileInputStream = loader.getResourceAsStream("user.json");
String fileJSONContents = new String(userJsonFileInputStream.readAllBytes(), StandardCharsets.UTF_8);
//Create a unique example for each File/JSON
Example createExample = OASFactory.createExample()
.description("User JSON Description")
.value(objectMapper.readValue(fileJSONContents, ObjectNode.class));
// Save your Example with a Unique Map Key.
examples.put("createExample", createExample);
} catch (IOException ioException) {
System.out.println("An error occured" + ioException);
}
return examples;
}
}
The controller using createExample
as its @ExampleObject
.
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
@APIResponses(
value = {
@APIResponse(responseCode = "200", content = @Content(
mediaType = "*/*",
examples = {
@ExampleObject(name = "boo",
summary = "example of boo",
ref = "createExample")
}
))
}
)
public String hello() {
return "Hello RESTEasy";
}
}
In your application.properties, specify the following: Take note that it references the full package path of the Filter.
mp.openapi.filter=org.acme.OASModelFilter
Contents of user.json file:
{
"hello": "world",
"my": "json",
"testing": "manually adding resource JSONs as examples"
}
The JSON file used is located directly under resources. Of course you can change that path, but you need to update your InputStream.
mvn clean install
mvn quarkus:dev
Go to http://localhost:8080/q/swagger-ui/
and you will now see your user.json file contents displayed
Hopes this helps you,
References for my investigation: