1

How does the 2 differ in terms of actual usage?

In DDD, we use a repository to get Aggregate Roots and persist them.

We forget about the implementations and focus on the domain and so it doesn't matter where we are taking the data from.

That being said, why does ACL exists?

Usual examples of ACL is when getting data from "legacy" app or simply just from getting data from another bounded context e.g "User Management" to "Discussion" context.

Here's a Microsoft article about ACL.

  • Why not have a repo instead that has the same methods? i.e why not just call it a repo too?
  • Why is an anti-corruption layer considered a domain service?
  • What is the semantics?

Even with codes aside and just sticking to discussing in DDD domain modelling mentality, what differs between ACL and a Repo?

To clarify what's an ACL in this context, these answers from another question explains it:


If anyone happen to know about IDDD (Blue book) by Vaughn Vernon:

Let's use the Collaboration context from the IDDD example. Actual codes here:

If it was to be a repo, the actual implementation might be called "HttpCollaboratorsRepository"

12
  • Why do you think CollaborationService is an anti-corruption later? Mar 20 at 14:36
  • 1
    @GregBurghardt i don't think it is an ACL, the book says it is an ACL. To quote "The trio of CollaboratorService, UserInRoleAdapter, and CollaboratorTranslator is used to form an Anticorruption Layer (3), the means by which the Collaboration Context will interact with the Identity and Access Context and translate the user-in-role representation into a Value Object for a specific kind of Collaborator" (page 464 of IDDD) Mar 20 at 14:40
  • 1
    A repository is an object you create to work in a more convenient way with a storage (like a database); this storage is often something that you (or your team) have control of. An ACL is envisioned as a layer (which just means a small or a large bundle of code at the periphery of the application) which aims to protect your system from rules imposed by the need to integrate with other systems, developed by other teams or organizations, over which you have very little influence (e.g. you can't make them confirm to your API, or you don't have much say in how communication protocols will work). Mar 20 at 19:02
  • 1
    Well, as much as you want to isolate your system and, to put it in DDD terms, maintain the integrity of the model, you also can't pretend that nothing else beyond your system exists - so what you do is you try to identify and understand the forces that affect your system/model and and limit their influence. That's what ACL is all about, it limits how far the detailed knowledge of external rules and concepts extends, by "translating" the external stuff into concepts (data structures, functions, way of working) that your system uses internally, and then back out. 1/2. Mar 20 at 19:43
  • 1
    Since the core of your system is "hiding" behind the ACL, the internals then generally don't need to know where the data came from, and the code working with it can be more cleanly expressed, and the internals are protected from non-essential changes to the external APIs (at least, that's the idea). But as I hinted earlier, every abstraction is imperfect: you can't literally treat data as if it's all in local memory all the time; some of these real-world considerations will affect things like the general workflow. It's a bit of a balancing act. 2/2 Mar 20 at 19:43

3 Answers 3

4

A repository is generally an object you create to work in a more convenient way with a storage (like a database). More specifically in DDD, it's a way to obtain or query for an aggregate that you can't otherwise navigate to; the role of the repository is to isolate the domain logic from storage and retrieval–related concerns. This storage is often something that you (or your team) have control of.

An ACL is envisioned as a layer (which just means a small or a large bundle of code at the periphery of the application) which aims to protect your system from rules imposed by the need to integrate with other systems, developed by other teams or organizations, over which you have very little influence (e.g. you can't make them confirm to your API, or you don't have much say in how communication protocols will work). Or, to isolate from a legacy system, where there are other things depending on it, so there's no plasticity - which again means you have no control (and with DDD, you're trying to come up with a model that's better suited than the legacy one).

Now, if you take a high level view, these are similar structurally (both introduce an abstraction of some sort), but the motivation is different, and how you go about implementing and maintaining each is influenced by different considerations and different forces.

"[...] doesn't that leak a technical behavior in the domain? knowing data will be taken from somewhere else not from ours?"

Well, as much as you want to isolate your system and, to put it in DDD terms, maintain the integrity of the model, you also can't pretend that nothing else beyond your system exists. So, what you do is you try to identify and understand the forces that affect your system/model, and then limit their influence. That's what ACL is all about, it limits how far the detailed knowledge of external rules and concepts extends, by "translating" the external stuff into concepts (data structures, functions, way of working) that your system uses internally, and then back out.

Since the core of your system is "hiding" behind the ACL, the internals then generally don't need to know where the data came from, and the code working with it can be more cleanly expressed. And the internals are protected from non-essential changes to the external APIs (at least, that's the idea), which may come about because of reasons that have nothing to do with you or your system.

Now, having an ACL is introducing various costs (it's more complicated, you need to maintain it, you need to translate data, etc.), but the assumption is that you're willing to pay that cost for the isolation you get. If you're not, a valid strategy to adopt might be to confirm to the 3rd-party API, which is a different tradeoff.

Anyway, as I hinted earlier, every abstraction is imperfect: you can't literally treat data as if it's all in local memory all the time, otherwise you'll run into feasibility issues (like performance hits, too many network hops, things of that sort). Some of these real-world considerations will affect things like the general workflow (and the business domain you're modeling is even likely to already have some of these considerations embedded in the way they do things). Remember, the goal of modeling is not to dream up some perfect abstraction irrespective of anything else; it is to find a clean, workable model that's roughly in alignment with how the domain people actually operate. So it's a bit of a balancing act.


Side note: be aware that people use the word "repository" in different contexts to indicate some storage-related object, but what's meant by it exactly (the exact role, code structure) is not entirely consistent across different sources (so you have to sort of check your assumptions when you read some article, see if there are some conceptual differences from what you've read previously, etc). In particular, the term might appear outside the context of DDD.


More info:

  1. If you are accessing an externally controlled database or if you are gathering data from multiple external sources, you can also have a repository on top of an ACL (the repository keeps the domain-logic code from being littered with retrieval-related details, the ACL translates incoming data into a form preferred by your system) as a temporary isolation strategy that allows you to experiment. See this talk by Eric Evans (author of DDD Blue Book) for more details (rewind to 31:33 if the link doesn't automatically take you there).

  2. Here's another video of Evans where he goes into when you'd introduce an ACL and why (rewind to 10:00 if the link doesn't automatically take you there).

1

If your definition of a repository is "it gets data from somewhere", then many things would count as a repository. In the field of IT (Information Technology), providing data is pretty much its bread and butter.
In practice, that definition of "providing data" is much too vague to specifically identify what repositories are used for.

Two things can be structurally similar but are used for different purposes; and therefore we tend to give them different names. That is the case here.

  • A repository hides away the implementation of the data store.
  • An ACL hides away the particular implementations of a legacy codebase (at least the ones you don't want in your revamped domain)

Concretely, the only overlap between a repository and an ACL is that they act as an abstraction for a source that is external to your domain (whether it's the data store or the legacy domain).

But this again is too vague of a description to be of any practical use to us. Anything that's not a single monolithic method is a form of abstraction - we're just arguing the degree of abstraction here, not the binary nature of its existence.

What your question boils down to is that you've oversimplified your definition of these patterns to a point where they look very similar, but you've glossed over the fact that pretty much all patterns would look very similar when subjected to this kind of oversimplification.

This is not unlike the cliché joke of going to a race track and asking a person what car they drive, only to have them respond "a red one". In this joke, the person has oversimplified a very detailed (but also very technical) distinction between car builds (make, model, engine, drivetrain, torque, output, ...), and oversimplified it to only observe its color.

That's sort of what you're doing here when comparing the repository and ACL pattern. Your observation isn't wrong, it's just lacking a needed level of nuance.

1

Repository is usually for data that your application owns. ACL is a an interface to read and translate someone else's data. I define it in the application layer and implement it in the infrastructure layer.

If you read the white paper by Eric Evans called Getting Started With DDD When Surrounded By Legacy Systems, on page 8 he recommends an approach where your new DDD app pretends to own the data (that's really owned by the legacy system) by implementing an "ACL-backed repository". So you your app thinks it's saving its own data, so it uses the repository. BUT, your repository implementation knowns it's only faking and uses the ACL :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.