Java records in open-api generator
Asked Answered
P

2

7

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.

Proteose answered 14/6, 2023 at 9:50 Comment(3)
You can't, at least using the open-api generator from Spring, you should find a external library for that generation purpose, I could recommend you github.com/sngular/scs-multiapi-plugin, I am not sure if they support inmutable models, but I am sure they could add it.Sharp
It's not possible, an issue has been opened a couple of years ago to track down the issue: github.com/OpenAPITools/openapi-generator/issues/10490Morgan
It is definitely possible by overriding the .mustache-templates. See openapi-to-java-records-mustache-templates.Bolognese
D
0

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.

openapi-record-schema

- 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.

ignored-record

- 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);
    }

}

a-simple-test-for-record

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'

the-response

Dentist answered 19/6 at 23:34 Comment(0)
B
0

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

Bolognese answered 8/9 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.