Skip to content

Instantly share code, notes, and snippets.

@tomas-langer
Created March 21, 2023 17:22
Show Gist options
  • Save tomas-langer/aebef311b6be74c696e37c9339c33c9c to your computer and use it in GitHub Desktop.
Save tomas-langer/aebef311b6be74c696e37c9339c33c9c to your computer and use it in GitHub Desktop.
Options for API module naming

API modules

Helidon historically did not have strict separation of API modules and implementation modules. Even though we do use interfaces (and mostly package local implementations), we co-locate these in the same module.

Since version 3.0.0 and introduction of tracing module, we have introduced the first "pure" API module. In Helidon 4.0.0, we will introduce more such modules:

  • tracing API (existing), implemented by OpenTracing, and OpenTelemetry
  • metrics API, implemented by MicroProfile Metrics implementation, Micrometer
  • pico API, implemented by helidon-pico-services
  • health API, used from Níma Observe Health (and currently reactive Health), also supported by MicroProfile Health implementation
  • config API (in common)
  • logging API (HelidonMdc, and LogConfig) + SPI, now called common

We may also introduce additional API modules with the introduction of Pico (annotations, exceptions, basic interfaces to be implemented)

As the current state is inconsistent, I propose the following options:

Option 1 (current dev guidelines)

API modules may be introduced, package, groupId, artifactId must be aligned

module-name -> groupId/artifactId, API package, SPI package helidon-metrics-api -> io.helidon.metrics/helidon-metrics-api, io.helidon.metrics.api, io.helidon.metrics.api.spi helidon-tracing -> io.helidon.tracing/helidon-tracing, io.helidon.tracing, io.helidon.tracing.spi

In this case, the tracing module should be renamed, to have consistent approach (to helidon-tracing-api) In this case we could use ther "base" module as the implementation, such as: helidon-metrics-api and helidon-metrics helidon-pico-api and helidon-pico

Option 2 (use API module, base package)

API modules may be introduced, groupId and artifactId are aligned, package does not use api. This approach would make a strict rule - if there is an -api module, there MUST NOT be a base module.

module-name -> groupId/artifactId, API package, SPI package helidon-metrics-api -> io.helidon.metrics/helidon-metrics-api, io.helidon.metrics, io.helidon.metrics.spi helidon-tracing -> io.helidon.tracing/helidon-tracing, io.helidon.tracing, io.helidon.tracing.spi

In this case, we can see that helidon-tracing and helidon-tracing-api would use the same package, so only one of them can exist. Again we would need to rename helidon-tracing to helidon-tracing-api Implementation modules MUST have a suffix in name (such as helidon-tracing-opentracing, helidon-pico-services If we choose this option, we have to decide what should the default implementation module be called (or we keep it open)

Option 3 (never use API module)

API modules must be the "base" module, implementation must be differentiated by some suffix. This approach would follow development guidelines as they are now.

module-name -> groupId/artifactId, API package, SPI package helidon-metrics -> io.helidon.metrics/helidon-metrics, io.helidon.metrics, io.helidon.metrics.spi helidon-tracing -> io.helidon.tracing/helidon-tracing, io.helidon.tracing, io.helidon.tracing.spi

In this case we would need to rename helidon-metrics-api to helidon-metrics, helidon-pico-api to helidon-pico, and helidon-metrics to something new (helidon-metrics-?) Implementation modules MUST have a suffix in name (such as helidon-tracing-opentracing, helidon-pico-services If we choose this option, we have to decide what should the default implementation module be called (or we keep it open)

Option 4+

Maybe I have missed an option we could use, please propose it!

@tomas-langer
Copy link
Author

That is one of the reasons this started. Do we want to make it clear, when you use "just" API, and leave the choice implementation to the user?

In case of Pico, this is quite important:

  1. Service code, that needs to generate types (and uses annotations, such as Contract) should only need the API
  2. Application needs the full implementation

Now if the artifact id is helidon-pico-api, it is clear you only depend on API and you do not expect this to be a full impl.
If you depend on helidon-pico, I would not be sure - is this just API or impl? I would probably expect full impl.

On the other hand I do not like the impl suffix, so we need a good way of handling this - as a combination of helidon-pico-api and helidon-pico could only work if we use the existing rules for package structure

@barchetta
Copy link

I'm a step behind on this. Spoke a bit with Romain yesterday, and I think I prefer Option 3. To organize my thoughts I wrote up some use cases here: Structure of Helidion Modules

I'm not sure I got it right, but maybe it's helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment