Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Find a better name for @NamedInterface #75

Open
odrotbohm opened this issue Sep 12, 2019 · 7 comments
Open

Find a better name for @NamedInterface #75

odrotbohm opened this issue Sep 12, 2019 · 7 comments
Assignees
Labels
type: enhancement New feature or request

Comments

@odrotbohm
Copy link
Collaborator

odrotbohm commented Sep 12, 2019

Context

A Moduliths module exposes types for other modules to be allowed to use. The default set of types consists of all public types in the module's base package.

- com.acme
- com.acme.module
  + PublicType <- implicit API, because public and in the module package
  o PackageProtectedType

If the module contains sub-packages, all types in the sub-packages are considered internal.

- com.acme
- com.acme.module
  + PublicType <- implicit API, because public and in the module package
  o PackageProtectedType
- com.acme.module.internal
  + PublicType <- unaccessible by other modules

@NamedInterface exists to annotate packages (and soon types, see #74) to define a named set of types to act as a dependency target.

- com.acme
- com.acme.module.api
  - package-info.java // annotated with e.g. @NamedInterface("API"), makes all public types API
  + PublicType 
  o PackageProtectedType
- com.acme.module.internal
  + PublicType <- unaccessible by other modules
- com.acme.module.spi
  - package-info.java // annotated with e.g. @NamedInterface("SPI"), makes all public types SPI
  + PublicType 
  o PackageProtectedType

Problem

The term "named interface" was used to describe that kind of concept, originating from Sonargraph, that exposed that concept in its architecture modeling language. However, using "interface" in a term used inside a Java codebase creates confusion as it's not immediately clear whether you're talking about a Java interface or Moduliths named interface.

Alternatives

UML exposes the same kind of concept as "port" (see this article). Using port might create a few connections towards Hexagonal Architecture and it's ports & adapters concept. While you can implement such an architecture with Moduliths, I wonder whether we should create such strong ties.

Suggestions?

@odrotbohm odrotbohm added the type: enhancement New feature or request label Sep 12, 2019
@odrotbohm odrotbohm self-assigned this Sep 12, 2019
@simonbrowndotje
Copy link
Collaborator

What about something like "published" or "exported" ... the Java module system uses similar concepts for distinguishing between public and published types.

@odrotbohm
Copy link
Collaborator Author

But published or exported what? I feel like there should be a noun for this concept as it's named it's something that can be referred to.

@codecholeric
Copy link
Collaborator

@ModuleAPI 😉

@ttulka
Copy link

ttulka commented Sep 12, 2019

published sounds sensible. What about @PublishedContract?

@slyoldfox
Copy link

@odedia
Copy link

odedia commented Sep 20, 2019

The annotation sounds more like a command to me. So perhaps something like @AllowAccess, @AllowExternalAccess or @ExposeInterface?

@poulhenriksen
Copy link

The name I've been using, and is also used in the readme of this project, is public. I agree that a noun would be useful especially if re-using something like public which is already heavily used in Java. Since this annotation is very specific to a package level, maybe @PublicPackage? public components is also mentioned a few times in the readme, so maybe @PublicComponent. I also like @ModuleAPI suggestion by @codecholeric as it makes it very clear that this is related to modules and not something else..

Related, I would really like a way to specify that all subpackages should be public as well, but that might be out-of-scope for this task - unless it can be solved by the same annotation with some configuration on the annotation. My use-case for this is:

We want to introduce modules in our monolith, but it is currently split in layers. While we carve out the modules, there will be a lot of code "outside" the modules. This "outside" code will use some of the new modules and I want to enforce that they only use the public interface of those modules. At the same time, this outside code is already split into the layers, and I would like to represent these as a kind of module as well (for generating the diagrams primarily), BUT since these modules are not proper modules with a public and internal part, they should not be forced to have any internal parts, since they rely on each others internals/subpackages.

I could use @NamedInterface for this, but that means adding it on all subpackages package-infos (we have quite a lot). Instead, ideally, I would like to be able to specify that all packages within a module are part of the public API - maybe an annotation @OpenModule, similar to @NamedInterface, but on the root of the module package-info. Or it could be a parameter on @NamedInterface specifying that all sub-packages should be considered as part of the public interface.
Or, it could be something similar to ApplicationModuleDetectionStrategy that gives an even more configurable (but complex) way of defining how the internals of a module is structured, maybe by explicitly defining what should be the Internal packages of a module (in my case, that would be none).

@odrotbohm, let me know if it is better if I create a separate feature request for this.

To scope-creep a bit more, it might also be worth considering if it should be possible to have an internal package of a module be available to other internal packages of the same module. I've not yet have a use for this, but I'm also currently only doing some POC with Moduliths, and could imagine this to be useful for slightly bigger components where more internal structure could be convenient. With the right name, I could see this be part of a @NamedInterface as well...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants