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:
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
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)
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)
Maybe I have missed an option we could use, please propose it!
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:
Contract
) should only need the APINow 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 ofhelidon-pico-api
andhelidon-pico
could only work if we use the existing rules for package structure