OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.88k stars 6.59k forks source link

[JAXRS-spec] Use Microprofile Openapi annotations instead of swagger #795

Open michbeck100 opened 6 years ago

michbeck100 commented 6 years ago
Description

Moving forward to OAS 3.0 the openapi-generator should have the option to switch from Swagger annotations in the generated code to annotations from the Microprofile OpenAPI Specification.

jmini commented 6 years ago

Yes this would be great...

Related discussion is #27 and the more I participate in the MicroProfile Project, the more I am convinced that it is the way to go.


My approach was more: we could propose a new generator for MicroProfile (also based on AbstractJavaJAXRSServerCodegen but with new templates). The more I think about it, the more I think that it will take some time to reach the maturity of the current generators.

With version containing breaking changes (4.0.0 or later) we could decided that this version is good enough to existing JaxRS generator that uses Swagger 2 components.


Is your issue just a wish or are you ready to invest time on it (development, testing, ...)?

Let me know, maybe we can work together on it.

michbeck100 commented 6 years ago

Currently my approach is to remove the swagger annotations by using a boolean switch in the mustache templates. Because the microprofile openapi spec allows to merge YAML API definition with annotations, it is enough to have just the YAML definition together with the generated code.

jmini commented 6 years ago

I did not understood your last point:

Because the microprofile openapi spec allows to merge YAML API definition with annotations, it is enough to have just the YAML definition together with the generated code.

michbeck100 commented 6 years ago

The Microprofile OpenAPI specification allows to have just the API definition as single YAML file without any annotations in code (see here):

In this case, we refer to the OpenAPI document as the "source of truth", by which the client and provider must abide.

michbeck100 commented 6 years ago

And this section describes merging the YAML with annotations.

arthurdm commented 6 years ago

+1 to supporting MP OpenAPI!

that's an interesting approach @michbeck100 - if someone already has an OpenAPI v3 YAML file before the code they're likely (but not exclusively) using a design-first approach, in which case the code should not deviate from the static file..which creates the question on whether or not do we need OAS3 annotations at all?

Looking from the other side of the coin, I think that it's probably good to generate the MP OpenAPI annotations for some reasons:

So perhaps this issue can be staged:

Stage 1: generate a pure JAX-RS app from an OAS3 doc (also adding META-INF/openapi.yaml) Stage2: augment Stage 1's generated code to also generate MP OpenAPI annotations.

Thoughts?

jmini commented 6 years ago

As I wrote in #809, I think it would be nice to have 2 generators:

=> I am open for better name.

The generators should produce a meaningful project (README, pom.xml, ...) so that it is easy for the user to start.

The generator could also provide the possibility to select the implementation. The "library" option can be (mis)used to allow to pre-configure one app server:

As far as I understood switching implementation is only a matter of different libraries in the pom and chapter in the readme.

=> also open for feedback.


For "Stage 1" we are not that far: JAXRS-spec generator with other config can be almost reused.

michbeck100 commented 6 years ago

Stage 1 is already finished with #813. It just removes all swagger parts like annotations, imports and dependencies.

@arthurdm IMHO when using the contract-first approach, there is actually no need for any extra annotations in the first place. Every annotation generated from the static file would be "duplicate code", because of the ability to merge the static file with annotations. The only thing that makes sense, is to add the dependency to org.eclipse.microprofile.openapi:microprofile-openapi-api, so the developer can start to use the annotations without compile error. But do we need a separate generator for this? If #809 is fixed, i would say no, not necessarily.

For the code-first approach it makes sense to create a new generator. This would translate the static file into annotations and ignore the static file completely. This would then be the java-microprofile generator (stage 2). And i like the idea to pre-configure for one app server.

jmini commented 6 years ago

(Stage 1) But do we need a separate generator for this? I would say no, not necessarily.

I agree.

My reasons are more "marketing" oriented:

igbch commented 6 years ago

Hi, I like a lot the contract first approach and I think each change should go first to the contract and then to code, so I like what @michbeck100 is proposing and I follow his changes in the code-generator (which are working using openliberty), but I also share the thoughts of @arthurdm about the possibility of code-first. Out there in the community you always find both flavors and so to have support for both would be great and helps the microprofile community to have full support, I vote for stage 1 and stage 2 and look forward to test it.

jmini commented 6 years ago

Hi @igbch, @michbeck100, @arthurdm,

Any pointer on how what we described as "(Stage 1)" in this issue works? (doc: static OpenAPO files).

I have tried to run a simple project with:

I did not managed to get it running. A simple project would help to create the corresponding generator.

I think that java-microprofile-spec-file is a better generator name for this approach.

igbluz commented 6 years ago

I just open a sample1-helloworld on github for demonstration how to use openAPI v3 with OpenLiberty v18.0.0.3. It does not use any swagger package. Does it help?

tjquinno commented 5 years ago

As people have mentioned already, there are the contract-first and code-first styles and I agree that it would be valuable if the generator supported both.

There's a third style in which the same developer sometimes updates the contract first and at other times updates the code first. She might start out by defining the contract, then use a tool like this one, then as she adds endpoints to the code (adding the annotations along with it) the contract becomes obsolete until she updates it or generates/fetches it as with the support for OpenAPI in MicroProfile. One could argue this is a messy approach, but I'd think it is out there.

For that reason might it be useful to include the MicroProfile OpenAPI annotations in the generated code -- at least provide an option to do that? Even though, as mentioned earlier, that would replicate what the OpenAPI document conveys, doing so would not affect the functionality.

jmini commented 5 years ago

I have started to work on this again... (targeting Quarkus in my case, but any other app server like OpenLiberty, Thorntail, …) should works too.

I spoke about this earlier this week:

Serving the OpenAPI Spec: Annotation Based or Static file

-- I really think that we need to support both approaches:

Especially in the second case, using the generation-gap pattern is interesting:

You consider that the JAX-RS endpoints must be generated: they only delegate to an other class that need to implement an interface that is also generated. Such a pattern is implemented in the jaxrs-jersey generator.

jmini commented 5 years ago

For the "Static file" approach, I have proposed PR https://github.com/OpenAPITools/openapi-generator/pull/3901

jmini commented 4 years ago

The OpenAPI annotations are definitively the way to go!

It now seems that the SmallRye OpenAPI project provides a way to use those annotations on top of Spring instead of JaxRS.

bollerdominik commented 1 year ago

Is there a solution for this?

miguelborges99 commented 1 year ago

Created the PR #15407 to add Microprofile OpenAPI annotations.

@jmini @michbeck100

miguelborges99 commented 1 year ago

The PR #15407 enables Microprofile OpenAPI annotations when option "useMicroProfileOpenAPIAnnotations" is set to true. It is possible to have both Microprofile OpenAPI annotations and Swagger annotations in the same generated code. Here is an example, using openapi-generator-maven-plugin, on how to use it:

 <plugin>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>${version.openapi.generator.maven.plugin}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <inputSpec>${project.basedir}/../openapi.yaml</inputSpec>
                        <generatorName>jaxrs-spec</generatorName>
                        <apiPackage>com.yyy.services</apiPackage>
                        <modelPackage>com.yyy.api.model</modelPackage>
                        <invokerPackage>com.yyy.api</invokerPackage>
                        <generateSupportingFiles>false</generateSupportingFiles>
                        <generateApiTests>true</generateApiTests>
                        <generateModelTests>true</generateModelTests>
                        <generateAliasAsModel>true</generateAliasAsModel>
                        <configOptions>
                            <sourceFolder>src/main/java</sourceFolder>
                            <sourceFolder>src/gen/java</sourceFolder>
                            <java8>true</java8>
                            <library>quarkus</library>
                            <useMicroProfileOpenAPIAnnotations>true</useMicroProfileOpenAPIAnnotations>
                            <useJakartaEe>true</useJakartaEe>
                            <useSwaggerAnnotations>false</useSwaggerAnnotations>
                            <dateLibrary>java8-localdatetime</dateLibrary>
                            <serializationLibrary>jackson</serializationLibrary>
                            <interfaceOnly>true</interfaceOnly>
                            <returnResponse>true</returnResponse>
                            <useTags>true</useTags>
                        </configOptions>
                    </configuration>
                </execution>
            </executions>
        </plugin>

@wing328 Is it possible to speed up the merge of this PR?

miguelborges99 commented 1 year ago

The PR #15407 was merged in master branch, it is expected to be released in version 6.6.0.