quarkiverse / quarkus-openapi-generator

OpenAPI Generator - REST Client Generator
Apache License 2.0
119 stars 80 forks source link

Support for plain Java clients #82

Open wtrocki opened 2 years ago

wtrocki commented 2 years ago

Extension provides solution for generating performant Quarkus Java Client. I'm opening thread to discuss investigation I'm doing to validate non Quarkus use cases.

Why

Quarkus community want to provide first class quarkus support and implement capabilities like async support. For some of the cases we need to have more universal support:

Differences between Quarkus and Plain Java generator

See: java client in https://openapi-generator.tech/docs/generators/java

Possible questions to get answered

1) Is it worth complexity to add generic java use case for Quarkus generator. Should that bee done in this repo or separate generator should be provided based on quarkus generator? 2) When introducing generic java support - would that mean having 2 separate generators or one generator serving both use cases. 3) How introduction of java generator will affect quarkus use cases? Can we add abstractions for quarkus specific areas. 4) Should we inherit design and avoid generating pom.xml for the java case? 5) How features like Async Support will work with Generic and Quarkus use cases? Would every new feature need 2 different implementation of interface 6) Would generic generator work with Quarkus. Would be have conflicts of dependencies? 7) Can generic generator be popularized by listing it on openapi generator page? https://openapi-generator.tech/docs/generators

ricardozanini commented 2 years ago

Hey, @wtrocki many thanks for this proposal ❤️ . Please see my replies inline.

  1. Is it worth complexity to add generic java use case for Quarkus generator. Should that bee done in this repo or separate generator should be provided based on quarkus generator?

I believe we can start adding this feature in this repo, and move to another if things get harry. We rely on openapi-generator, which is spec parser + context variables provider. The generated code is based on Qute Templates, so I think for a first exploration work we could add more templates and add a codegen property for the user to choose the output (quarkus or plain java).

  1. When introducing generic java support - would that mean having 2 separate generators or one generator serving both use cases.

It's one generator, with the option to output plain java instead of Quarkus classes

  1. How introduction of java generator will affect quarkus use cases? Can we add abstractions for quarkus specific areas.

I don't think so. I agree with adding an abstraction level if needed. Such as templating functions specifically to handle Quarkus or Java.

  1. Should we inherit design and avoid generating pom.xml for the java case?

The goal of this extension is to stick only to java classes that are added to the project's classpath. So that users can inject them into their own classes. I believe for Java, we won't have CDI support, but rather factories so client code can easily access them.

  1. How features like Async Support will work with Generic and Quarkus use cases? Would every new feature need 2 different implementation of interface

We would need only different templates as I see now. Maybe some template functions, not much. The only thing is to avoid adding non-quarkus dependencies to the Java use case, which I believe we won't.

  1. Would generic generator work with Quarkus. Would be have conflicts of dependencies?

I don't think so. We can stick with the dependencies we already have on Quarkus use case. Foe example, the quarkus-jackson brings the jackson library. We just use the jackson library directly if needed for the plain java use case.

  1. Can generic generator be popularized by listing it on openapi generator page? https://openapi-generator.tech/docs/generators

I believe we can yes, add this extension there saying that we use their generator under the hood, but the use case is different. Rather than generating the whole project, we integrate the generated classes into the development cycle. Generated classes are added to the already existing project.

Please let me know if you have any folllow-up questions.

wtrocki commented 2 years ago

This is amazing feedback. Two follow ups:

1) How do you envision java case work - would we document what libraries users add manually to their pom?

2) I think to move further I need capability/documentation on how to add custom templates to modify behaviour of the generator. I tried the classic openapi generator way but as mentioned - this extension using different templating engine so that would not work. When experimenting with custom templates we can identify missing elements from the model and contribute that back if needed.

ricardozanini commented 2 years ago

Thank you!

Here's the follow-ups:

How do you envision java case work - would we document what libraries users add manually to their pom?

I'd say to instruct users to manually add them in runtime. We already do that, see: https://github.com/quarkiverse/quarkus-openapi-generator#oauth2-authentication

I think to move further I need capability/documentation on how to add custom templates to modify behaviour of the generator.

Well, we don't have a doc, but I think you can take inspiration from these: https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/deployment/src/main/resources/templates

I would add a quarkus and java sub dirs there to distinguish between them if needed.

About the context injection (the variables from the parsed OpenAPI spec), you can debug the DefaultGenerator class from the inner generator: https://github.com/OpenAPITools/openapi-generator/blob/v5.4.0/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java#L385

All the "generate*" methods have a mapping context variable that we can use in the templates :)

Would be nice to document all of these, though. 😞

krisv commented 2 years ago

+1 on trying to do it in one extension, and use abstractions with potentially different implementations where (and only where) necessary. I believe that shouldn't conflict with the Quarkus use cases (and let's see what challenges we run into when attempting this).