OHS ... Open Host Service
AL ... Application Layer
ACL ... AntiCorruption Layer
BC ... Bounded Context
1.
Here I'll use the term unidirectional when our OHS's public interface can only be used by external BCs to call our system, but it can't be used by our BCs to call external systems
Similarly, I'll use the term bidirectional when our OHS's public interface can be used by external BCs to call our system, but it can also be used by our BCs to call external systems
a) Is OHS unidirectional or can it also be bidirectional? I'd say it can only be unidirectional?
b) Similarly, is AL unidirectional or can it also be bidirectional? I'd say it can only be unidirectional?
2. I assume OHS doesn't replace AL, but instead sits on top of Application services/AL?
3.
a) Should OHS also be used for communication between BCs that are part of the same application or should it only be used for communication with external BCs? Whatever the answer, please elaborate your reasoning?
b) Assuming BCs communicating with each other are part of the same application and assuming we don't use OHS - should these BCs communicate with each other directly ( ie. BC would call ACL, which in turn would make a direct call to BC ) or via AL ( ie. BC would call ACL, which would call AL, which then would make a direct call to BC )?
I'd argue that these BCs should communicate directly and not via AL, since it may bloat AL's interface and may also expose inner functionality to external systems?
4.
Eric Evan's DDD book, pg. 375:
Open Host Service uses a standardized protocol for multiparty integration. It employs a model of the domain for interchange between systems, even though that model may not be used internally by those systems.
a) I assume our OHS should use our application's domain model only as the basis for its own model? In other words, OHS shouldn't use application's domain model, but should instead just base its very own model on it?
b) Since our OHS has it's very own model ( which is usually based on Core Domain, whatever that may be ), I assume that we should also define a translation/anticorruption layer sitting between OHS and the rest of our application?
c) Are arguments and return values of Application services defined in terms of application's domain model?
5.
Does BC always use Infrastructure services to call another BC ( of course if BC is using ACL, then BC would call ACL, which in turn would call Infrastructure layer, which would then call the other BC ), regardless if that other BC is external or part of the same application?
thanks
EULERFX:
1.
1b) An ACL is bidirectional in that data flows in either direction - either when you're sending a message to external service or interpreting a message received from said service.
a) By "or interpreting a message received from said service" you mean only that our ACL can receive a reply ( ie. return value ) from the called external BC or do you also mean that the same ACL which sends messages ( on behalf of our BCs ) can also interpret the messages when external BCs call our BCs?
b) If the former, then isn't in that sense OHS also bidirectional since OHS services called by external systems can also send reply ( ie. return value ) back to these external systems? If the latter, in 4b) you said OHS itself also acts as a translator, which suggests that ACL used by our BC for calling external systems won't also be used when external systems call our BC, which would imply that ACL can't be bidirectional?
3.
3b) Assuming BCs communicating with each other are part of the same application and assuming we don't use OHS - should these BCs communicate with each other directly ( ie. BC would call ACL, which in turn would make a direct call to BC ) or via AL ( ie. BC would call ACL, which would call AL, which then would make a direct call to BC )?
If not using OHS, call the application service of the other BC.
a) So you're saying that BC should call ACL, which would call AL, which then would make a direct call to the other BC?
b) Do BCs within the same application share the same AL?
c) If internal BCs do share the same AL, doesn't this mean that we may be forced to define some Application services whose only purpose is to enable internal BCs to communicate with each other ( thus external clients are not meant to call these particular Application services ). As such, don't these Application services expose inner functionality to external clients?
Clarification: I know that external clients can only directly call our Application services if they have a reference to dll containing our Application services, but if some clients do have a reference to such dll, then there's a possibility they may call Application services intended to be used only by internal BCs calling each other?
4.
b)
I assume that we should also define a translation/anticorruption layer sitting between OHS and the rest of our application?
In effect, the OHS will be that translation layer. It will delegate all behavior to application service, in the process adapting to the specific technology used to implement OHS.
According to Evans, OHS should use the underlying domain model only as the basis for its own model, meaning the two models should be separate "instances".
Domain models should be completely oblivious to anything except the domain they model. Don't same rules also apply to OHS model? In other words, shouldn't OHS model be unaware of other layers and domains and as such it shouldn't be bothered with translating messages from its own model into the domain model encapsulated by the underlying AL?
c)
Are arguments and return values of Application services defined in terms of application's domain model?
define interface in terms of DTOs
Assuming the interfaces of Application Services are defined in terms of DTOs: OHS is defined in terms of OHS model and the Application Services encapsulate the domain model, but what model defines these DTOs? In other words, are these DTOs part of OHS model, part of domain model encapsulated by AL or... ?
5.
Does BC always use Infrastructure services to call another BC ( of course if BC is using ACL, then BC would call ACL, which in turn would call Infrastructure layer, which would then call the other BC ), regardless if that other BC is external or part of the same application?
It can be said that regardless of whether the called BC is internal or external, you still employ an ACL to one degree or another.
a) Shouldn't ACL be applied only when there's a danger of the outside model leaking into our model?
b) Since internal BCs ( BCs within the same application ) should talk to each other via AL, I assume you'd have these BCs call AL via Infrastructure layer, since Domain layer shouldn't have any dependencies on upper layers ( ie. AL )?
c) So you disagree with @mrhobo, which states that internal BCs should communicate with each other directly ( if BC is using ACL, then BC would directly call ACL, which in turn would call the other BC ) and not via AL? Why?
EULERFX, second update:
1.
b)
If the latter, in 4b) you said OHS itself also acts as a translator, which suggests that ACL used by our BC for calling external systems won't also be used when external systems call our BC, which would imply that ACL can't be bidirectional?
The translation performed by the OHS, while similar to an ACL is different in nature because it is of a technical character.
So what did Evans mean by ( pg. 368 ) "ACL can be bidirectional" , since if communication is implemented as you suggest, then ACL can never be bidirectional ( while ACL1 used by BC1 can receive a reply from BC2, ACL1 will never be used when BC2 calls BC1, even if both BC1 and BC2 are internal – note that I'm aware that BC2 will use its own ACL, I'm just pointing out that Evans talks about bidirectional ACLs. In other words, he's implying that when BC2 calls BC1, this call would be received by ACL1 )?
3.
c) If internal BCs do share the same AL, doesn't this mean that we may be forced to define some Application services whose only purpose is to enable internal BCs to communicate with each other ( thus external clientsare not meant to call these particular Application services ). As such, don't these Application services expose inner functionality to external clients?
As above, BCs should share application services even if they internal. That doesn't make much sense.
a) I assume it's a typo and you meant shouldn't instead of should?
b) Internal BC also don't share OHS?
c) If internal BCs communicated with each other via OHS, wouldn't we face same problems as when these BCs communicate via AL ( ie. we may be forced to define some OHS services whose only purpose is to enable internal BCs to communicate with each other, and as such these OHC services may expose inner functionality to external clients )?
5.
a)
Shouldn't ACL be applied only when there's a danger of the outside model leaking into our model?
Yes, but that will always be the case if you're calling some external BC. If the BCs are locally owned then you can have some mutual agreement on model (shared kernel), but it is still often easier to decoupled them.
I thought even when decoupled, we can still have a simple translation layer ( instead of full blown ACL ) if the public interface between two BCs is simple enough ( at least that's how I understood Evans )?
MRHOBO
3.
b)
Assuming BCs communicating with each other are part of the same application and assuming we don't use OHS - should these BCs communicate with each other directly ( ie. BC would call ACL, which in turn would make a direct call to BC ) or via AL ( ie. BC would call ACL, which would call AL, which then would make a direct call to BC )?
The AL is meant to separate the domain from it's users and ways of usage. Different BC's living within the same application should not communicate through such layers, but should instead be part of the same domain layer.
So you disagree with @eulerfx about internal BCs calling each other through AL? Why?
2)
I assume OHS doesn't replace AL, but instead sits on top of Application services/AL?
It could sit on top of an AL, but could also sit directly on top of the BC. An AL and a OHS are very similar. If all usage of the BC depends on the OHS, in my opinion, there is little need to create an in between AL.
Could you clarify in what situations all usage of BC would depend only on OHS and when would it also depend on AL?
4.
b)
Since our OHS has it's very own model ( which is usually based on Core Domain, whatever that may be ), I assume that we should also define a translation/anticorruption layer sitting between OHS and the rest of our application?
You will need adaptors to translate between the domain model and the interaction model, yes. The ACL, however, is meant to integrate two BC's in such a way that the BC that uses the ACL is unaware of the existence of another BC. This comes in handy for a client using an OHS, but should not go in between the OHS and the BC on the server side.
In other words, the translator between OHS and AL shouldn't be ACL, but instead just a "regular" translator?
“Open Host Service” defines a protocol that gives access to your sub-system as a set of services. “Event Publisher” communicates with other bounded contexts through domain events that can be consumed by other bounded contexts. “Customer/Supplier” establishes a clear customer/supplier relationship between the two teams.
In DDD, a Domain Service is a specific type of domain layer class that we use when we want to put some domain logic that relies on two or more entities.
The anti-corruption layer contains all of the logic necessary to translate between the two systems. The layer can be implemented as a component within the application or as an independent service.
You only need a Domain Service if the piece of domain logic you are modelling does not naturally fit on any Domain Object. A common scenario for this is when the responsibility of the action does not naturally fit on any particular object or if it requires multiple Domain Objects in order to co-ordinate the action.
1.a) Is OHS unidirectional or can it also be bidirectional? I'd say it can only be unidirectional?
Exactly, a service that needs to access other services through it's own interface is not a service at all.
1.b) Similarly, is AL unidirectional or can it also be bidirectional?
Similarly, a layer that needs to access layers that use that layer is not a layer at all. As with all layered architecture: dependencies go one way only.
2) I assume OHS doesn't replace AL, but instead sits on top of Application services/AL?
It could sit on top of an AL, but could also sit directly on top of the BC. An AL and a OHS are very similar. If all usage of the BC depends on the OHS, in my opinion, there is little need to create an in between AL.
3.a) Should OHS also be used for communication between BCs that are part of the same application or should it only be used for communication with external BCs? Whatever the answer, please elaborate your reasoning?
It all depends on your use-cases, requirements and environment. An OHS is usually not cheap to build and maintain and are usually avoided for cost and simplicity's sake. There might be good reasons to have an OHS within the same application though, for example when the application needs to be distributed for availability or performance reasons or when several teams are working on different locations on different interchangeable parts of the application.
3.b) Assuming BCs communicating with each other are part of the same application and assuming we don't use OHS - should these BCs communicate with each other directly ( ie. BC would call ACL, which in turn would make a direct call to BC ) or via AL ( ie. BC would call ACL, which would call AL, which then would make a direct call to BC )?
BC's can communicate in many different ways, directly and indirectly. These are the patterns outlined by DDD: Customer/Supplier, Shared Kernel, anti-corruption layer, etc. To be clear: the Application Layer, however, is not one of them. The AL is meant to separate the domain from it's users and ways of usage. Different BC's living within the same application should not communicate through such layers, but should instead be part of the same domain layer. Which pattern should be used to integrate BC's again depends. An ACL comes in handy when working with legacy code, but is certainly not the most optimal solution if you are in control of both BC's as is the case with most application development.
4.a) I assume our OHS should use our application's domain model only as the basis for its own model? In other words, OHS shouldn't use application's domain model, but should instead just base its very own model on it?
Yes. If you don't separate your domain model from your interaction model you are not domain modeling anymore. Interaction models usually involve concepts that have nothing to do with the domain.
4.b) Since our OHS has it's very own model ( which is usually based on Core Domain, whatever that may be ), I assume that we should also define a translation/anticorruption layer sitting between OHS and the rest of our application?
You will need adaptors to translate between the domain model and the interaction model, yes.
The ACL, however, is meant to integrate two BC's in such a way that the BC that uses the ACL is unaware of the existence of another BC. This comes in handy for a client using an OHS, but should not go in between the OHS and the BC on the server side.
4.c) Are arguments and return values of Application services defined in terms of application's domain model?
They can be yes. This is done quite often to save time, but it should not cause your domain model to become application aware.
5) Does BC always use Infrastructure services to call another BC ( of course if BC is using ACL, then BC would call ACL, which in turn would call Infrastructure layer, which would then call the other BC ), regardless if that other BC is external or part of the same application?
Communication between BC's do not always have to cross layers. As I've said before, several BC's can live within the same domain layer and can be integrated in several ways outlined by DDD. This applies when the BC's are part of the same non-distributed application. When BC's are distributed, then these BC's will need to use an infrastructure layer to interact with their external counterpart.
Update
So you disagree with @eulerfx about internal BCs calling each other through AL? Why?
Yes, it seems I do.
An application layers' responsibility is to abstract application logic from other types of logic (like presentation and infrastructure logic) and to create a single point of truth within an application. The application layer pattern was not defined by DDD and is not a BC integration pattern, like shared kernel, conformist, customer/supplier and anti-corruption layer. One application has one application layer. It is not wrong what eulerfx suggests when you think of the application layer as a facade around the BC, which it often is, but that is simply not the definition of an application layer. Look it up if you will.
Could you clarify in what situations all usage of BC would depend only on OHS and when would it also depend on AL?
An AL and an OHS are quite similar. An AL is meant to be used within an application and an OHS for external communications. Both are facades. When your application has no presentation layer, only an OHS, there is no point in creating an application layer to go in between. When an application has a presentation layer but also exposes it's BC via an OHS, the presentation layer would use the AL and external systems would use the OHS, which would in turn would use the AL.
An OHS should depend on an AL if present, because an AL should be a single point of truth.
In other words, the translator between OHS and AL shouldn't be ACL, but instead just a "regular" translator?
Exactly.
An ACL is part of a BC, but in fact gets its information from another BC. This abstracts all the messy integration parts away and makes it possible for a BC to be coded in a way that fits the domain . An ACL prevents the BC from getting corrupted with these integration issues.
Here is a practical example: https://softwareengineering.stackexchange.com/questions/184464/what-is-an-anti-corruption-layer-and-how-is-it-used
1a) It doesn't make sense to call external systems through a BC's own open-host service. With your terminology, an open-host service is always unidirectional.
1b) An ACL is bidirectional in that data flows in either direction - either when you're sending a message to external service or interpreting a message received from said service.
2) Yes, an open-host service sits on top of application services. In a hexagonal architecture, it forms a port/adapter which adapts application layer to, say, HTTP.
3a) It depends and to determine a best solution, consider the benefits and drawbacks of OHS. The main benefit is encapsulation and when coupled with a published language, can create a standardized interface to access the service, regardless of technology. The OHS will typically be more stable than internal interfaces. A drawback is the amount of effort required to implement and maintain the OHS since effectively it is another layer.
3b) If not using OHS, call the application service of the other BC. This service can fully encapsulate the constituent domain by forming the interface entirely out of DTOs. Or you can return domain objects directly if caution is used. The AL forms a facade over the domain layer simplifying the interface. Calling domain objects directly is too granular.
4a) The OHS should stem from the domain model it encapsulates, but it will likely be different from models used by its clients which is why clients should create their own ACL.
4b) In effect, the OHS will be that translation layer. It will delegate all behavior to application service, in the process adapting to the specific technology used to implement OHS.
4c) See above. They can be, but then too much domain knowledge can leak. Instead, you can define interface in terms of DTOs - read models for queries and command objects for behaviors.
5) It can be said that regardless of whether the called BC is internal or external, you still employ an ACL to one degree or another.
UPDATE
1a) The former.
1b) If an external BC calls a local OHS then it has to call it in terms of the local OHS's published language - no local ACL is needed. An ACL in the external BC would perform the translation from the external BC's model to the language of local OHS. The translation performed by the OHS, while similar to an ACL is different in nature because it is of a technical character. It is translation, or better yet, adaptation of a domain model to, say, HTTP.
3a) Yes and the called AL would be part of the other BC - a facade over the other BC's domain model. A drawback of this approach however is that the hosting application would have to configure dependencies for all BCs that are interacting.
3b) No. Each BC would have a set of application services encapsulating the corresponding domain models. Communication between BCs, when not using OHS, would go across these application services and ACLs.
3c) As above, BCs should share application services even if they internal. That doesn't make much sense.
If you have access to DLL containing application service then you can do anything really. This is why OHS provides better encapsulation and interop.
4b) The OHS does have its own model, but this model is based around the domain model. The difference is that an OHS is an adapter between the domain model and some service technology. It is meant to expose the domain model. As such it is its responsibility to translate between its model and the domain model.
4c) They form the contract of the application layer, so they are a model of the application layer. They aren't part of domain model, but they form a facade around it. They aren't part of OHS model which has its own.
5a) Yes, but that will always be the case if you're calling some external BC. If the BCs are locally owned then you can have some mutual agreement on model (shared kernel), but it is still often easier to decoupled them.
5b) Yes, but note there is no requirement to have internal BCs call each other via AL directly. You still have OHS option.
5c) The problem with calling BCs directly and bypassing application service is that the interface is more complex and too granular. The benefits of application service are explained by the facade pattern. This is the discussion in the book about granularity.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With