I'm utilizing openapi-generator-maven-plugin
to generate Java classes for an API. We are using Nimbus to help with some related interactions, e.g. authentication.
The use of the OpenAPI-generated classes is very simple and elegant, however, I find that I miss some helper methods (getters) for extracting the method (e.g. GET
or POST
...) and URL (e.g. /v1/ping
) of the endpoints I'm accessing through the generated class.
My primary use case for the method and URL here is that they are required for me in my DPoP proof which I send alongside the access token (htm
and htu
claim).
Some mockup code of what I'd like to achieve:
ApiClient apiClient = new ApiClient();
SomeApi api = new SomeApi(apiClient);
prepareDpopProof(api.getMethodOfDoSomething(), apiClient.getBasePath() + api.getUrlOfDoSomething());
api.doSomething();
What I'm missing here from my current generated code is getMethodOfDoSomething()
and getUrlOfDoSomething()
. Is there some elegant way of "extracting" this from the generated code? I'd prefer not having to hardcode it and/or doing it manually.
My current plugin execution is fairly simple, so there may be several options I am unaware of:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.8.0</version>
<executions>
<execution>
<id>some_api</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${basedir}/src/main/resources/openapi/some_api.json</inputSpec>
<output>${project.build.directory}/generated</output>
<generatorName>java</generatorName>
<apiPackage>some.api.api</apiPackage>
<modelPackage>some.api.model</modelPackage>
<invokerPackage>some.api.client</invokerPackage>
<configOptions>
<useJakartaEe>true</useJakartaEe>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
While my question primarily requests a getter, I expect that such an option may not exist. In that case, I am interested in alternative ways of getting the method and URL of endpoints, preferably least hacky and least hardcoded.
I think there may be multiple ways to achieve this, e.g. reflection, but I ended up using an Interceptor
for the ApiClient
. This worked well for my particular case, since the DPoP proof can be added to the original request inside the Interceptor
. This original request knows both the "method" and "URL" of the API call, which are the values I wanted to have through getters.
Simplified layout:
DPoPInterceptor dpopInterceptor = new DPoPInterceptor();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(dpopInterceptor)
.build();
apiClient = new ApiClient();
apiClient.setHttpClient(okHttpClient);
SomeApi api = new SomeApi(apiClient);
api.doSomething();
Where my DPoPInterceptor
would, simplified, do something similar to this:
public class DPoPInterceptor implements Interceptor {
@Override
public @NotNull Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
String method = originalRequest.method();
String url = originalRequest.url().toString();
Request modifiedRequest = originalRequest.newBuilder()
.header("Authorization", "DPoP " + SOME_ACCESS_TOKEN)
.header("DPoP", generateDpopProof(method, url, SOME_DPOP_KEY)
.build();
return chain.proceed(modifiedRequest);
}
}
Where, depending on your other layout, you may need to take in e.g. an access token or a DPoP key in your interceptor to generate the DPoP proof. You may also need to trim the query parameters from the URL of the original request.