domain driven design – DDD: Viable approaches to integrating with external systems (Adapters, ACLs, Bounded Contexts)

Our team have been debating approaches to integrating external or third party systems when using DDD. The literature is extensive, but sometimes contradictory. Just like a UL helps us better understand and communicate about the domain, we wanted to do a better job of defining the different approaches, and when we might use each? We are not experts, so would be interested in any insights or feedback the community might have, and confirmation we are on the right track.

When integrating with a third-party technology, we identifier three different approaches we have used in the past: Adapters (specifically in regards to the Ports & Adapters Pattern), Anti-Corruption Layer and Bounded Contexts.

Acknowledging that there is overlap between each concept, we defined the following team guidelines:

  • An external system is always a separate bounded context — by its nature, the solution will use a different language to that of our domain.

When deciding how to integrate, use the following guidance:

  • Adapter: When the technology or interface with the external or third-party system is relatively stable, and any data translation required is minimal, or automated, use a basic port and adapter. If the service is integral to the domain model, provide an interface in the domain (as a domain service). Otherwise call directly from the Application layer. This is analogous to what is sometimes referred to as the infrastructure layer. Also referred to as a gateway. Examples include Repositories, Payment Gateways etc

  • Anti-corruption Layer: If the translation required is more complex in nature, or there is a high level of impedance between your context, and the third-party service, implement an ACL in your bounded context. This will include Adapter(s), and specialised Translation services for performing the complicated data transpositions needed. The ACL may provide a facade to set of more complex services provided by the external system. All communication with the ACL happens in the language of the bounded context. The ACL should limit itself to data translations.

  • Bounded Contexts: If you are looking to expand on the functionality of the third party service then create your own bounded context that wraps the external system, and adds to the feature set. Communication with this bounded context can still happen via an adapter or ACL. Or integration may now be achieved through messaging — your new bounded context can have its own adapter for publishing and consuming messages to and from other contexts.

Does anyone have any constructive feedback or critical ideas that they think would help improve our definitions. Or spots something that is incorrect or problematic?

domain driven design – Serialization in REST API: Generating Representations Based on a Model

I am developing a RESTful API using .NET technology to implement the service.

The part that I am having problems with is the dynamic nature of the representation types that the service will return.

For example, let’s say I have a Person model, and the Person has a bunch of Beyblades toys they can battle other people with.

My model would look something like:

public class Person{
  public guid ID {get; set;}
  public string Name {get; set;}
  public List<Beyblades> Beyblades{get; set;}
  //...
}

The API will return a list of People by going to “urlpeople”. The representation for the people returned will contain the person’s ID, name, and a link to “urlbeybladesperson-ID” that can be followed instead of the serialized list of their Beyblades (if they have any).

Seems pretty straightforward, but the implementation of a dynamically generating links for lists-of-things (and not the list’s themselves) is what I’m trying to find the best solution for.

My initial thought was to create templates for the representations returned. The template would check the model in order to output the correct representation data. For example, the template would check if the person has any Beyblades, and if so it would generate the link (instead of the serialized list of Beyblade models); likewise, it would generate a self link for each person as well.

The problem with this solution is that if my API is to support JSON (Hal), XML, and say HTML as possible representation output types, I would have to manage at least 3 templates whenever something in the model were changed.

My next thought is to design a serialization framework by implementing a series of MediaTypeFormatter types that would naturally consider my business logic to convert lists into appropriate links; however, this too could become problematic while maintaining the API since there would have to be some sort of standard mapping between lists of things and API URLs and this may not be apparent when changes are made.

Since REST is not a new thing, I was wondering if there .NET already has tools for serializing models into a RESTful representations?

Or if there was a best practices document/tutorial on this topic?

Or maybe I’m conceptually going about this wrong and someone here could point me in the right direction?

I realize that REST and OO doesn’t seem go hand-in-hand, so maybe there isn’t anything like what I am seeking. It just feels like I’m inventing a wheel that someone has probably already done.

domain driven design – Maintaining business rule consistency and validity for Aggregate Root’s child entity collection

Lets say we have DailySchedule Aggregate Root and Appointment Entity. DailySchedule AR owns a collection of Appointments. The idea is – we want to enforce the following business rule given by domain experts:

Daily Schedule cannot have two or more Appointments with the same time slot (e.g. Appointment starting 09:00 AM and ending 10:00 AM).

Now imagine two users at the same time are modifying Daily Schedule AR – adding a new Appointment with starting time of 09:00 AM and ending time of 10:00 AM. Both inserts will succeed because when AR was loaded initially and new Appointment was added, business rule was not violated, however in the end AR will be in invalid state.

How can this be avoided? Two of my ideas:

  1. Pessimistic db locking – lock users from modifying AR while another person is modifying it.
  2. Allow AR to be in invalid state and eventually somehow fix it, some sort of a process or event (eventual consistency).

domain driven design – Pattern to combine orders from different systems

We have a legacy order system and a new order system that are both currently active. The legacy order system takes ‘offline’ orders still, the new order system handles ‘online’ orders but uses the legacy order system for operations, so the legacy system has both offline and online orders. Eventually, the new system will handle all orders, but won’t have historical orders in it.

I need a solution that can source order information from both systems and display in a single ‘my orders’ view for customers. There are a number of cases/rules where the source of the data depends on how the order was created, e.g. the delivery address will come from the legacy system if it was an offline order, but the new system if it was an online order, the billing entity will always come from the legacy system.

As we move functionality these rules will change, i.e. for certain types of offline orders, the delivery address needs to come from the new system regardless of origin.

In some cases, the data may not be in the legacy system, so will be blank, but populated in the new system, so we need defaults and/or fallback (“if not in legacy system, find in new system”) behaviour for some data, e.g. products.

Is there a design pattern for this type of aggregation of two sources of data that would minimise future development required as we shift the ‘source of truth’?

Django + DRF and Domain Driven Design

Currently I am working on project with Django+DRF stack, but our project manager is a former .net-developer. Recently we had a conversation that backend is build without Domain Driven Design

Can someone explain me which patterns does django-rest-framework use and why it is not in “ddd style”?

domain driven design – Event logging – per Aggregate or one per Bounded Context?

I’m working on an application (using Onion Architecture) and I want to have good log of entities’ changes.

I’m struggling to find any good examples of what are the best practices – and I want to avoid bad architecture decisions at the beginning of my project.

Let’s say I have few Entities (Aggregates in fact): Customer, Product, Cart. This entities are persisted in following tables: Customers, Products and Carts.

These entities produce such events: CustomerCreated, CustomerDeleted, ProductCreated, ProductPriceChanged, CartCreated, CartProductAdded etc.

Question is:

Should I have single table (single event log store) for all my entities, e.g. named DomainEvents?

Or is it better to have single table log per entity, e.g. CustomersLog, CartsLog and ProductsLog.

I’m personally in favor for the latter, because it is in accordance to SRP, and I believe will make log reading much faster (e.g. we can have INDEX on Id in Logs tables and we know that this Id represents given entity).

domain driven design – How can we use DDD when data comes from API?

And since then my application is back to having all the logic in Service layer.

There are two things that you can do here.

The key idea is that “retrieving data” is a completely different concern from “processing” data. Retrieving data needs IO, so that concern is normally managed by your application components. Processing data is a problem for your domain logic.

So we use application code to get the data, then pass the in-memory representations of that data to the domain code.

One approach is to treat “retrieve the data” as something analogous to a domain service. So the domain model defines some interface that describes an implementation agnostic retrieve of the data, and the application implements an instance of that interface, wired up to the correct IO mechanism. For use cases that need the remote data, the interface of the aggregate root includes in its target method(s) an argument of the appropriate interface.

In effect you “dependency inject” the application’s implementation of the interface into the function.

An alternative approach is to have the domain model ask for the data it needs, which the application service retrieves and passes to the domain model as a value. So all of the IO concern lives in the application component, and the aggregate root acts like a little state machine that tells the application what it wants.

switch (root.state()) {
    case I_NEED_DATA:
        data = getTheData(root.args())
        root.onData(data)
        break
    //....
}

See Cory Benfield’s talk on Building Protocol Libraries to get a broader sense for how this might work.

If the distinction between the two styles in unclear, you might reflect on how you would write an isolated test for your domain code in each case. Using the first pattern, you would end up passing a test double (aka a “mock”) to the logic under test. In the second pattern, you would end up passing plain old data (because all of the I/O that you would otherwise need to mock away is invoked by the application code, not the domain code).

domain driven design – CQRS denormalized data query with multiple aggregates

Let’s say there’s a domain that’s similar to Reddit.

Aggregate roots are

Board // you can ignore this
  - boardId
Post
  - postId
  - userId
User
  - userId
  - username

where each aggregate emits

Post
  - PostCreated
User
  - UserCreated
  - UsernameUpdated

for the query side, the query will try to fetch a page of posts in a specific board.

Given this, the denormalized data should look as below

posts: ({
  title: 'some post title',
  body: 'some post body',
  author: 'user123',
})

Now in the denormalised database, I’d create post entry when the PostCreated event is received. And the received event holds userId.

To populate the author field for the read model above with that user ID, I can do either

  1. Read username from the existing denormalized User data, and save the post read model with the username.
    • This will require updating ALL posts when UsernameUpdated event is handled.
  2. Create a join column between User and Post. and when query is requested, join the table to populate the author field with username

Is it so obvious that the second method is the way to do it? The reason why it’s confusing me is that the denormalised database feels almost like a giant monolithic database (thinking of adding other aggregate root’s events to the read model E.g., Board). Or is denormalized data is just like this?

java – Leap Year Test Driven Development

I have asked to do an assignment on Leap Year API following test-driven development. But I scored less in the task and I don’t know where I have gone wrong. Can anyone please review my code in the git repository? Since they told me to commit on adding each test cases, I have done it in that manner. I am sharing the github link of my commit to get the accurate feedback.

Problem Statement:

Here’s the assessment: http://codingdojo.org/kata/LeapYears/ Please code this in Java using TDD. Make sure you keep committing as you add test cases, so we can see how your code evolves

My Code:

Link: https://github.com/srth12/LeapYearTDD

LeapYear.java:


package com.tdd.leapyear;

public class LeapYear {
    public boolean isLeapYear(int year) {
        if (isDivisibleBy400(year)){
            return true;
        }else if (isDivisibleBy100(year) && (!isDivisibleBy400(year))){
            return false;
        }else if (isDivisibleBy4(year) && !isDivisibleBy100(year)){
            return true;
        }else return isDivisibleBy4(year);
    }

    public boolean isDivisibleBy100(int year) {
        return (year % 100) == 0;
    }

    public boolean isDivisibleBy400(int year) {

        return (year % 400) == 0;
    }

    public boolean isDivisibleBy4(int year) {
        return (year % 4) == 0;
    }
}

LeapYearTest.java:

package com.tdd.leapyear;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.*;

public class LeapYearTest {

    private LeapYear leapYear;

    @Before
    public void setUp() {
        this.leapYear = new LeapYear();
    }

    @Test
    public void when2000_thenIsLeapYear(){
        assertTrue("Method should treat 2000 as a leap year", this.leapYear.isLeapYear(2000));
    }

    @Test
    public void when2008_thenIsLeapYear(){
        assertTrue("Method should treat 2008 as a leap year", this.leapYear.isLeapYear(2008));
    }

    @Test
    public void when200_thenIsDivisibleBy100(){
        assertTrue("Method should return true for 200 as it's divisible by 100",
                this.leapYear.isDivisibleBy100(200));
    }

    @Test
    public void when350_thenIsDivisibleBy100(){
        assertFalse("Method should return false for 350 as it's not divisible by 100",
                this.leapYear.isDivisibleBy100(350));
    }

    @Test
    public void when200_thenIsDivisibleBy400(){
        assertFalse("Method should return false for 200 as it's not divisible by 400",
                this.leapYear.isDivisibleBy400(200));
    }

    @Test
    public void when800_thenIsDivisibleBy400(){
        assertTrue("Method should return false for 800 as it's divisible by 400",
                this.leapYear.isDivisibleBy400(800));
    }

    @Test
    public void whenNonLeapYear_thenIsLeapYear(){
        List<Integer> nonLeapYears = Arrays.asList(1700, 1800, 1900, 2100, 2017, 2018, 2019);
        for (Integer year: nonLeapYears) {
            assertFalse(year + " should be non leap year, but isLeapYear method" +
                    " returned True", this.leapYear.isLeapYear(year));
        }
    }

    @Test
    public void whenLeapYears_thenIsLeapYear(){
        List<Integer> validLeapYears = Arrays.asList(2012, 2016);
        for (Integer year: validLeapYears) {
            assertTrue(year + " should be non leap year, but isLeapYear method" +
                    " returned True", this.leapYear.isLeapYear(year));
        }
    }

    @Test
    public void when200_thenIsDivisibleBy4(){
        assertTrue("Method should return true for 200 as it's divisible by 4",
                this.leapYear.isDivisibleBy4(200));
    }

    @Test
    public void when35_thenIsDivisibleBy4(){
        assertFalse("Method should return false for 35 as it's not divisible by 4",
                this.leapYear.isDivisibleBy4(35));
    }

    @After
    public void tearDown() {
        this.leapYear = null;
    }
}

Search Engine in a Database Driven Site

Advertising

y u no do it?

Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

Starts at just $1 per CPM or $0.10 per CPC.