Skip to content

Discussion: How to Structure Integrations

Tim Quinn edited this page Feb 2, 2021 · 11 revisions

We have several integrations of Helidon with other technologies, for both Helidon SE and Helidon MP. I have built another one—​for Micrometer support—​and before I recreate the PR for it Tomas suggested in a Slack DM that we have a broader discussion for how to handle these integrations.

So far, we have used various approaches for how to structure the Helidon SE and Helidon MP modules for these integrations, as Tomas summarized:

Layout Location for SE module Location for MP module

First-class citizen

helidon/xxx

helidon/microprofile/xxx

Integration-level citizen, two modules

helidon/integrations/xxx/xxx

helidon/integrations/xxx/cdi

helidon/integrations/xxx/base

helidon/integrations/xxx/cdi

Integration-level citizen, one module

helidon/integrations/xxx

Layout Advantages Disadvantages

First-class citizen

Follows our familiar approach of putting SE modules as children of the top-level and modules for Helidon MP under microprofile.

Not really appropriate if xxx is not truly a MicroProfile technology. e.g., Micrometer

Two modules, repeat xxx for SE

Follows our familiar approach which separates the Helidon SE and Helidon MP code.

Seems slightly odd to repeat the technology name in the SE module location.

Two modules, use base for SE

Follows our familiar approach which separates the Helidon SE and Helidon MP code.

base does not add much information

One module

Reduces the number of modules in the system.

Looks slightly odd to have annotations in a module that is usable from Helidon SE. CDI behavior of xxx is triggered somewhat indirectly by the app developer declaring a dependency on some other module that has a harder dependency on CDI.

The "Integration-level citizen, one module" approach (e.g, Neo4J) declares a dependency on CDI using

<scope>provided</scope>
<optional>true</optional>

To follow the principle that no modules should be on the runtime classpath unless they are used, other dependencies—​such as for a module that defines annotations—​would be declared the same way in our integration module. Further, the developer would need to declare a dependency to make sure that such modules will be present at runtime.