Can I generate immutable models with open api generator without changing the mustache templates? My first thought was that the generator could be configured to generate Java records but I can't find any information on how to do this. I've also included the @Value lombok annotation in the generator config but setters are still generated due to the caveat that I have to modify the mustache templates to omit setters which is not currently an option.
I understand that it is not yet possible to use record
with the OpenApi Generator, I want to do it too.
For my part the use of mustache
I think it requires a learning curve, that few will want to live it.
But as an option what we are doing in our project is the use of OpenApi Generator Ignore
Is a file that you include for the generator to ignore the classes you want, plus a tag in the pom.xml
to process this file.
The record
as such, must be created by you, and include it in your Apis project if you have it separated from backend, also you must upload the src/main/java
folder to your repository at least with the record, in my case it was necessary for nexus
to build the artifact with the record inside, you can then decompile the .jar to test.
This record is for the typicode
response https://jsonplaceholder.typicode.com/todos/2
Source
This is not the perfect example but it can be useful, I have included the src/main/java
just for having a record generated by me.
Springboot version
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
OpenApi generator version
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.2.0</version>
- ignoreFileOverride tag
<ignoreFileOverride>${project.basedir}/src/main/resources/openapi-rest/.openapi-generator-ignore</ignoreFileOverride>
- TestRecordResponse
The @Jacksonized
annotation in the record I am using it for testing purposes but if you want you can remove it, it is working for me with or without it.
@Builder
@Jacksonized
public record TestRecordResponse(
@Schema(name = "userId", example = "1", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
String userId,
@Schema(name = "id", example = "2", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
String id,
@Schema(name = "title", example = "quis ut nam facilis et officia qui", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
String title,
@Schema(name = "completed", example = "false|true", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
Boolean completed) {
}
The Schema annotation seems to be necessary for this case, when I write it in the openapi-rest.yml
the documentation is not displayed in the swagger.
In other words, it is not enough to write this.
TestRecordResponse:
type: object
properties:
id:
type: string
example: "2"
userId:
type: string
example: "1"
title:
type: string
example: "quis ut nam facilis et officia qui"
completed:
type: boolean
example: true | false
the following image shows a better documented record now.
- Ignored record
When you build your api with maven, in the logs you should be able to see something like this, which indicates that your record is intact.
- A simple test
import static org.assertj.core.api.Assertions.*;
class WebClientSimpleTypiCodeTest {
@SneakyThrows
@ParameterizedTest
@MethodSource("getTestRecord")
@DisplayName("A simple get to the endpoint of the free jsonplaceholder service typicode.com")
void simpleGet(final TestRecordResponse expectedTestRecordResponse) {
final CountDownLatch latch = new CountDownLatch(1);
WebClient.create("https://jsonplaceholder.typicode.com")
.get()
.uri("/todos/2")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(TestRecordResponse.class)
.log()
.doOnTerminate(latch::countDown)
.subscribe(actualTestRecordResponse -> {
assertThat(actualTestRecordResponse)
.isNotNull()
.usingRecursiveComparison()
.isEqualTo(expectedTestRecordResponse);
});
latch.await();
}
private static Stream<TestRecordResponse> getTestRecord() {
final TestRecordResponse expectedTestRecordResponse = TestRecordResponse.builder()
.id("2")
.userId("1")
.title("quis ut nam facilis et officia qui")
.completed(false)
.build();
return Stream.of(expectedTestRecordResponse);
}
}
The curl
This was the response with the image-1
of the deployed source https://github.com/rucko24/gitlab-test
curl -X 'GET' 'http://localhost:8082/api/v1/test-record' -H 'accept: application/json'
If you use openapi-generator-maven-plugin
, I have created mustache templates which will generate simple Java records - without lombok or any other custom annotations.
These mustache templates can be found here: openapi-to-java-records-mustache-templates @ GitHub
© 2022 - 2024 — McMap. All rights reserved.
.mustache
-templates. See openapi-to-java-records-mustache-templates. – Bolognese