OpenAPITools / OpenAPITools/openapi-generator
[BUG][Quarkus] REST-client interfaces in Quarkus sends empty payloads when used with GraalVM native compilation
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Description
I have a Quarkus application which has three modules: api, app and ext. api is a module that contains an Openapi file which specifies the API for the application itself and which Openapi-generator uses to generate interfaces which are implemented within app. ext on the other hand contains Openapi contracts for external APIs which my service connects to, and generates interfaces that are injected as REST clients in app.
@ApplicationScoped
@Slf4j
public class CustomerFacade {
@Inject
@RestClient
RestClient1 restclient1;
@Inject
@RestClient
RestClient2 restclient2;
public String getCustomerId(String id) {
var request = orc.acme.ext.modell.<RETRACTED>.Input.builder()
.dto(List.of(DTO.builder().id(id).category(1L).build())).build();
log.debug(((Integer) request.getDTO().size()).toString());
log.debug(request.getDTO().get(0).toString());
var response = restclient1.fetch("", "88880001", "", 0, request);
return onlyOne(response.getServiceReturnValue()).getCustomerId();
}
//...
}
This works without issues in a jar build. However, with a native build, the issue seems to be that the request body becomes empty. I've tried debugging it using the above log statements, as well as container logs, which all verified that the connection works as expected, the headers (for example the number 88880001) are properly attached and the request body POJO is properly generated before the REST client gets it. However, what is actually sent by the REST Client is an empty {}. We also don't use custom additional application.properties' files in this application, which otherwise could be a source of frustration but one that also has been migitated since then.
I tried adding these lines in application.properties:
quarkus.native.enable-http-url-handler=true
quarkus.native.enable-https-url-handler=true
Did not solve the issue. I also tried adding *serializableModel: "true" in configOptions, also did not work. Same with
additionalModelTypeAnnotations: "@javax.enterprise.context.ApplicationScoped"
which also did not work.
openapi-generator version
Version 6.1.0 initially. Incremented to 6.4.0 which is the latest version my organisation provides. Did not solve the issue.
OpenAPI declaration file content or url
Only the body has been included because the scope of the issue seems to be limited to it, and the fields have been changed due to the actual APIs being confidential.
components:
schemas:
Input:
example:
lookup:
- customerid: customerid
period:
end: end
start: start
updated:
source: 1
timestamp: timestamp
category: 0
entity:
id: 0
identity: identity
id: id
- customerid: customerid
period:
end: end
start: start
updated:
source: 1
timestamp: timestamp
category: 0
entity:
id: 0
identity: identity
id: id
Generation Details
In build.gradle for the ext module:
fileTree("${project.projectDir}/contract").matching { exclude "\\.*" }.each { file ->
def api = file.getName().substring(0, file.getName().lastIndexOf("."))
def taskName = "openApiGenerate${api.substring(0, 1).toUpperCase()}${api.substring(1)}"
def subProject = "${project.properties.get("group")}.extern.ext"
tasks.create(taskName, GenerateTask.class) {
generatorName = "jaxrs-spec"
inputSpec = file.getPath()
outputDir = "$project.buildDir/generated"
apiPackage = "${subProject}.resurser"
modelPackage = "${subProject}.modell.${api}"
configOptions = [
// additionalModelTypeAnnotations: "@javax.enterprise.context.ApplicationScoped",
booleanGetterPrefix : "is",
dateLibrary : "java8",
generateBuilders : "true",
interfaceOnly : "true",
library : "quarkus",
returnResponse : "false",
// Prevent dependency on swagger in API
useSwaggerAnnotations: "false",
useTags : "true",
useBeanValidation : "true",
]
globalProperties = [
apiTests : "false",
modelTests: "false"
]
}
compileJava.dependsOn(taskName)
}
Steps to reproduce
Create a multi-module Quarkus project that uses Openapi-generator to generate REST client interfaces. Inject these interfaces in an @ApplicationScoped bean, and create a POST request, maybe using the body specification above. Use builders. Build the application using GraalVM and then trigger code that uses the REST client generated by Openapi-generator.
Related issues/PRs
Suggest a fix
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated client and model configuration in the ext module's build.gradle, then reproduce the POST request with a Quarkus native build as described. Compare the native request body with the working JAR build; done means the generated REST client sends the populated payload instead of {}.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100