I realize while looking for resources about hexagonal architecture that
I probably used port/adaptor words differently from what they are
supposed to mean.

I'll ask some friends to correct me on that matter.

On Tue, 2020-05-19 at 20:41 +0900, David Leangen wrote:
> Hi Matthieu,

> > * `ports` that define some APIs required for `domain cores`
> > (mailbox-
> > api is a port)
> Ok, this is interesting because it is exactly the opposite approach
> from what I am used to. :-)
> I am used to designing the API first. Since the API is exposed to the
> outside, it usually requires a lot of thought. Then an implementation
> gets built that satisfies the API. Since the implementation is
> “private”, it can be changed or updated whenever necessary (or there
> can even be multiple implementations at once), so it doesn’t require
> quite as much thought as the API. Definitely the API should remain as
> stable as possible, as changing it affects all of its users.
> It sounds from your description that the implementation (core) is
> done first, then the API is more of an afterthought.
> Or did I misunderstand?

We have the same definition of what an API and an implementation is.
It's the reason why APIs have contract testsuites: they are important
and require stability.

What you miss in the picture, and I guess you should read more about
hexagonal architecture, is that a core domain is a component that is
written in pure Java (no technical dependency) that encapsulate the
logic of a given domain.

The `port` concept is here to say "I will need to store that email
somewhere, so I define an API because I don't care how it works as long
as it works with plain Java objects. Please write an implementation of
that API and give it to me".

> > * `adapters` that provides the implementation of a `port` (mailbox-
> > cassandra)
> But if mailbox is a “core” component implementation, that has an
> adapter, and also has multiple other implementations… Sorry, I’m a
> bit confused. Maybe an image would help?

An hexagon defines some ports (the component it needs to work), some
adapters (the implementations it provides to other hexagons) and a core
domain: the logic of this hexagon.

Note that an hexagonal `core domain` can very well be just
`infrastructure` (adaptor) for another hexagon. 

It's not layers but a recursive architecture.

And sorry, I can't find illustration about that.

> > When we define a `port` API we provide a contract testsuite to
> > check
> > that the implementations will work well plugged-in.
> Yeah… like I said, this is backwards from what I am used to. :-)
> My fear is: if the API is just an afterthought that is placed over
> the implementation, how do you know if it was well designed?

Because it fits the `core domain`. The `core domains` are what matters
in a software, everything else is just technical details.
> > So to come back to the analysis: the right level of abstraction for
> > James architecture is these three entities.
> Those sounds like very abstract architectural entities to me,
> something like a “database table” or a “queue” or some other general
> construct. Or am I misunderstanding?
> In my mind, if you were to say that they are just “categories” of
> actual James entities, perhaps that would make more sense to me. For
> example: “A Mailbox is a core entity in the James domain, and happens
> to be one of the core entities” makes sense to me, but it is the
> Mailbox that is the entity, not “a core” that is an entity. Does that
> make sense? Or again, am I completely misunderstanding what you are
> trying to say?
> > Unfortunately, there's not way to visualize the hexagons from the
> > code
> > right now.
> :-)
> Ok, that should be our objective I guess, then. The code should match
> the domain model, so it should be easy to find our way around in the
> code.

`Core domains` are a bit hidden in the current code (it can be an
abstract class for example) so the easiest way to draw our hexagons is
to review *-api projects: they describe the boundaries between

It could be fun to draw the hexagons for various profiles actually.

> > Finally, I see Guice module documentation as a problem: we usually
> > document things that are supposed to last. Documentation reduces
> > the
> > ability to refactor things.
> Yes, that makes sense. Really it should be the API that is
> documented, as normally (again from my experience) the API is the
> representation of the domain model in code.

APIs are just boundaries. That means it can be the boundary for the
user facing features but also the boundary between your imap protocol
and your mailbox `core domain`.

> > As Guice modules are technical classes, I would not like to be
> > refrained from refactorings because of this documentation.
> Completely agree!!
> > It's why I think we have to find a way to document `ports` and
> > `adapters` because they are definitely more stable.
> I agree with this statement, notwithstanding the things above that I
> said I was having trouble understanding.
> If you could give me a list of the cores, ports, and adapters, I’ll
> see what I can do with that, and perhaps make progress in my
> understanding of the code base.

Let's look at quota-mailing for example.

The `core domain` is located in `quota-mailing`.
It provides an implementation of `GroupMailboxListener`.
It requires an implementation of `EventStore`.

Then you have `quota-mailing-memory` which provides a memory
implementation of `EventStore` for `quota-mailing`.

And `quota-mailing-cassandra` which provides a cassandra implementation
of `EventStore` for `quota-mailing`.

I hope it helps.


Matthieu Baechler

To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to