All Projects → ttulka → ddd-example-ecommerce

ttulka / ddd-example-ecommerce

Licence: MIT License
Domain-driven design example in Java with Spring framework

Programming Languages

java
68154 projects - #9 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to ddd-example-ecommerce

ftgogo
FTGOGO - event-driven architecture demonstration application using edat
Stars: ✭ 82 (+12.33%)
Mutual labels:  ddd, event-driven, hexagonal-architecture
go-hexagonal http api-course
Ejemplos del curso de API HTTP en Go aplicando Arquitectura Hexagonal
Stars: ✭ 78 (+6.85%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
Designpatternslibrary
A comprehensive design patterns library implemented in C#, which covers various design patterns from the most commonly used ones to the lesser-known ones. Get familiar with and learn design patterns through moderately realistic examples.
Stars: ✭ 485 (+564.38%)
Mutual labels:  design, architecture, oop
Software Engineer Interview Questions
A lot of questions and links to prepare yourself for an interview.
Stars: ✭ 176 (+141.1%)
Mutual labels:  ddd, architecture, oop
eventide-postgres
Event Sourcing and Microservices Stack for Ruby
Stars: ✭ 92 (+26.03%)
Mutual labels:  soa, event-driven, service-oriented-architecture
Library
This is a project of a library, driven by real business requirements. We use techniques strongly connected with Domain Driven Design, Behavior-Driven Development, Event Storming, User Story Mapping.
Stars: ✭ 2,685 (+3578.08%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
teamo-ddd-example
Implementing Domain Driven Design in PHP using Laravel
Stars: ✭ 46 (-36.99%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
Todomvc Ddd Cqrs Eventsourcing
Implementation of basic Todo app via tastejs/todomvc in C#/Typescript with eventsourcing, cqrs, and domain driven design
Stars: ✭ 134 (+83.56%)
Mutual labels:  ddd, example, domain-driven-design
ddd-for-python
A domain-driven design framework for Python.
Stars: ✭ 30 (-58.9%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
kingdom-python-server
Modular, cohesive, transparent and fast web server template
Stars: ✭ 20 (-72.6%)
Mutual labels:  ddd, event-driven, hexagonal-architecture
Architecture
.NET 6, ASP.NET Core 6, Entity Framework Core 6, C# 10, Angular 13, Clean Code, SOLID, DDD.
Stars: ✭ 2,285 (+3030.14%)
Mutual labels:  ddd, architecture, domain-driven-design
DDD
Domain-Driven Design example
Stars: ✭ 116 (+58.9%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
Event Sourcing Jambo
An Hexagonal Architecture with DDD + Aggregates + Event Sourcing using .NET Core, Kafka e MongoDB (Blog Engine)
Stars: ✭ 159 (+117.81%)
Mutual labels:  ddd, domain-driven-design, event-driven
Dotnet New Caju
Learn Clean Architecture with .NET Core 3.0 🔥
Stars: ✭ 228 (+212.33%)
Mutual labels:  ddd, domain-driven-design, event-driven
Goes
Go Event Sourcing made easy
Stars: ✭ 144 (+97.26%)
Mutual labels:  ddd, domain-driven-design, event-driven
awesome-software-architecture
A curated list of awesome articles, videos, and other resources to learn and practice software architecture, patterns, and principles.
Stars: ✭ 1,594 (+2083.56%)
Mutual labels:  ddd, oop, event-driven
Eshoponcontainersddd
Fork of dotnet-architecture/eShopOnContainers in full DDD/CQRS design using my own patterns
Stars: ✭ 126 (+72.6%)
Mutual labels:  ddd, example, domain-driven-design
Eventflow.example
DDD+CQRS+Event-sourcing examples using EventFlow following CQRS-ES architecture. It is configured with RabbitMQ, MongoDB(Snapshot store), PostgreSQL(Read store), EventStore(GES). It's targeted to .Net Core 2.2 and include docker compose file.
Stars: ✭ 131 (+79.45%)
Mutual labels:  ddd, domain-driven-design, event-driven
repository
[PHP 7] Implementation and definition of a base Repository in Domain land.
Stars: ✭ 26 (-64.38%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture
educational-platform
Modular Monolith Java application with DDD
Stars: ✭ 124 (+69.86%)
Mutual labels:  ddd, domain-driven-design, hexagonal-architecture

DDD Example Project in Java: eCommerce

The purpose of this project is to provide a sample implementation of an e-commerce product following Domain-Driven Design (DDD) and Service-Oriented Architecture (SOA) principles.

Programming language is Java 11 with heavy use of Spring framework.

# build
./mvnw clean install

# run 
./mvnw spring-boot:run

# open in browser http://localhost:8080

Table of Contents

Domains

Several Business Capabilities have been identified:

Core Domain

  • Sales
    • put a product for sale
    • categorize a product
    • update a product
    • change a product price
    • validate an order
    • place an order

Supporting Subdomains

  • Warehouse

    • stack goods
    • fetch goods for shipping
  • Billing

    • collect a payment
  • Shipping

    • dispatch a delivery

Later, we can think about more supporting domains (not implemented in this project):

  • Marketing

    • discount a product
    • promote a product
  • User Reviews

    • add a product review
  • Customer Care

    • resolve a complain
    • answer a question
    • provide help
    • loyalty program

The e-commerce system is a web application using a Portal component implementing the Backends For Frontends (BFF) pattern.

The idea of Microfrontends is implemented in an alternative branch.

Event Workflow

The communication among domains is implemented via events:

Event Workflow

When the customer places an order the following process starts up (the happy path):

  1. Shipping prepares a new delivery.
  2. Sales creates a new order and publishes the OrderPlaced event.
  3. Shipping accepts the delivery.
  4. Billing collects payment for the order and publishes the PaymentCollected event.
  5. Warehouse fetches goods from the stock and publishes the GoodsFetched event.
  6. Shipping dispatches the delivery and publishes the DeliveryDispatched event.
  7. Warehouse updates the stock.

There is only the basic "happy path" workflow implemented with a big room for improvement, for example when Shipping doesn't get bot Events within a time period, the delivery process should be cancelled etc..

Services Dependencies

Services cooperate together to work out the Business Capabilities: sale and deliver goods.

The actual dependencies come only from Listeners which fulfill the role of the Anti-Corruption Layer and depend only on Domain Events.

Event and Listener

Events contain no Domain Objects.

For communication across Services an Event Publisher abstraction is used, located in the package ..ecommerce.common.events. The interface is an Output Port (in the Hexagonal Architecture) and as a cross-cutting concern is its implementation injected by the Application.

Architectural Overview

While no popular architecture (Onion, Clean, Hexagonal, Trinity) was strictly implemented, the used architectural style follows principles and good practices found over all of them.

  • Low coupling, high cohesion
  • Implementation hiding
  • Rich domain model
  • Separation of concerns
  • The Dependency Rule

The below proposed architecture tries to solve one problem often common for these architectural styles: exposing internals of objects and breaking their encapsulation. The proposed architecture employs full object encapsulation and rejects anti-patterns like Anemic Domain Model or JavaBean. An Object is a solid unit of behavior. A Service is an Object on higher level of architectural abstraction.

Screaming Architecture

The architecture "screams" its intentions just by looking at the code structure:

..ecommerce
    billing
        payment
    sales
        category
        order
        product
    shipping
        delivery
    warehouse

Going deeper the technical concepts are visible too:

..ecommerce
    billing
        payment
            jdbc
        listeners
        rest

Packaging

As shown in the previous section, the code is structured by the domain together with packages for technical concerns (jdbc, rest, web, etc.).

Such a packaging style is the first step for a further modularization.

The semantic of a package is following: company.product.domain.service.[entity|impl], where entity and impl are optional. Full example: com.ttulka.ecommerce.billing.payment.jdbc.

Assembling

While a physically monolithic deployment is okay for most cases, a logically monolithic design, where everything is coupled with everything, is evil.

To show that the Monolith architectural pattern is not equal to the Big Ball Of Mud, a modular monolithic architecture was chosen as the start point.

The services can be further cut into separate modules (eg. Maven artifacts) by feature:

com.ttulka.ecommerce:ecommerce-application
com.ttulka.ecommerce.sales:catalog-service
com.ttulka.ecommerce.sales:cart-service
com.ttulka.ecommerce.sales:order-service
com.ttulka.ecommerce.billing:payment-service
com.ttulka.ecommerce.shipping:delivery-service
com.ttulka.ecommerce.warehouse:warehouse-service

Or by component:

com.ttulka.ecommerce.billing:payment-domain
com.ttulka.ecommerce.billing:payment-jdbc
com.ttulka.ecommerce.billing:payment-rest
com.ttulka.ecommerce.billing:payment-events
com.ttulka.ecommerce.billing:payment-listeners

In detail:

com.ttulka.ecommerce.billing:payment-domain
    ..billing
        payment
            Payment
            PaymentId
            CollectPayment
            FindPayments
com.ttulka.ecommerce.billing:payment-jdbc
    ..billing.payment.jdbc
        PaymentJdbc
        CollectPaymentJdbc   
        FindPaymentsJdbc     
com.ttulka.ecommerce.billing:payment-rest
    ..billing.payment.rest
        PaymentController
com.ttulka.ecommerce.billing:payment-events
    ..billing.payment
        PaymentCollected
com.ttulka.ecommerce.billing:payment-listeners
    ..billing.payment.listeners
        OrderPlacedListener

Which can be brought together with a Spring Boot Starter, containing only Configuration classes and dependencies on other modules:

com.ttulka.ecommerce.billing:payment-spring-boot-starter
    ..billing.payment
        jdbc
            PaymentJdbcConfig
        listeners
            PaymentListenersConfig
    META-INF
        spring.factories

Note: Events are actually part of the domain, that's why they are in the package ..ecommerce.billing.payment and not in ..ecommerce.billing.payment.events. They are in a separate module to break the build cyclic dependencies: a dependent module (Listener) needs to know only Events and not the entire Domain.

See this approach in an alternative branch: modulith.

Anatomy of a Service

Service is the technical authority for a specific business capability.

  • There is a one-to-one mapping between a Bounded Context and a Subdomain (ideal case).
  • A Bounded Context defines the boundaries of the biggest services possible.
  • A Bounded Context can be decomposed into multiple service boundaries.
    • For example, Sales domain contains Catalog, Cart and Order services.
  • A service boundaries are based on service responsibilities and behavior.
  • A service is defined by its logical boundaries, not a physical deployment unit.

Application is a deployment unit. A monolithic Application can have more Services.

  • Bootstrap (application container etc.).
  • Cross-cutting concerns (security, transactions, messaging, logging, etc.).

Application and Services

Configuration assemblies the Service as a single component.

  • Has dependencies to all inner layers.
  • Can be implemented by Spring's context @Configuration or simply by object composition and Dependency Injection.
  • Implements the Dependency Inversion Principle.

Gateways create the published API of the Service.

  • Driving Adapters in the Hexagonal Architecture.
  • REST, SOAP, or web Controllers,
  • Event Listeners,
  • CLI.

Use-Cases are entry points to the service capabilities and together with Entities form the Domain API.

  • Ports in the Hexagonal Architecture.
  • No implementation details.
  • None or minimal dependencies.

Domain Implementation fulfills the Business Capabilities with particular technologies.

  • Driven Adapters in the Hexagonal Architecture.
  • Tools and libraries,
  • persistence,
  • external interfaces access.

Source code dependencies point always inwards and, except Configuration, are strict: allows coupling only to the one layer below it (for example, Gateways mustn't call Entities directly, etc.).

Service Anatomy

Example of a Service Anatomy

As a concrete example consider the Business Capability to find payments in Billing service:

  • Application is implemented via Spring Boot Application.
  • PaymentJdbcConfig configures the JDBC implementations for the Domain.
  • Gateway is implemented as a REST Controller.
  • Use-Case interface FindPayments is implemented with PaymentsJdbc in Use-Cases Implementation.
  • Entity Payment is implemented with PaymentJdbc in Entities Implementation.

Service Anatomy

There is no arrow from Configuration to Gateways because PaymentController is annotated with Spring's @Component which makes it available for component scanning the application is based on. This is only one possible approach. Another option would be to put the Controller as a Bean into the Configuration, etc..

Conclusion

The goal of this project is to demonstrate basic principles of Domain-Driven Design in a simple but non-trivial example.

For the sake of simplicity a very well-known domain (e-commerce) was chosen. As every domain differs in context of business, several assumption must have been made.

Although all fundamental use-case were implemented, there is still a room for improvement. Cross-cutting concerns like authentication, authorization or monitoring are not implemented.

Where to Next

Check out the alternative branches and repos to see additional concepts and technologies in action:

  • Modulith: A separate Maven module per service.
  • Microfrontends: Service Web Components as part of the service codebase.
  • Microservices: Deployments with Docker and Kubernetes.
  • Kotlin: The same project again, this time in Kotlin.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].