This package support to build a complex application with domain driven design.

Overview

ddd-ts

The library implement Domain Driven Design for Nodejs base on Typescript.

Description

This package support to build a complex application with th domain driven design.

Install

#npm
npm i --save @typeddd/common @typeddd/domain  @typeddd/infrastructure reflect-metadata

#yarn
yarn add @typeddd/common @typeddd/domain  @typeddd/infrastructure reflect-metadata

Getting started

🤔 What is Domain-Driven Design?

Domain-Driven Design (DDD) is a method for developing a team's understanding of a problem space. It emphasises placing the primary focus of a project on the core area of the business (the core domain). This often takes the form of facilitated workshops with domain experts and the development of a shared set of conceptual models. DDD has the additional benefit of creating a shared understanding (ubiquitous language) between teams when designing technical solutions.

DDD (Domain Driven Design)

Thank you for document 4lessandrodev

1. Ubiquitous language:

  • Language and terms agreed upon by both business users and developers, within a bounded context
  • Entities with the same name in a different context can have different behavior and data
  • Bounded context helps in single responsibility for domain models

2. Rich domain model:

  • Models (entities, value objects, aggregates) with rich behavior are preferred over anemic domain models (entities without behavior, which only keep data and represent the DB tables)
  • Due to single responsibility principle (a class or method should have only one reason to change), non-cohesive behavior should be delegated to other classes (or even handled inside domain services) when necessary
  • Model methods can also delegate the task to domain services by raising domain events

3. Thin domain service working on rich domain models:

  • Domain services should not hold state (application services are not domain services, they are on the outer layer close to the UI layer, and can hold application/task state)
  • Domain services have very little behavior and only which does not fit cohesively in any domain model
  • Domain services sit in the core domain layer along with entities, value objects, aggregates and domain events, and expose domain models in their interfaces

4. Layers in a DDD application:

  • Core domain layer (domain services, entities, value objects, aggregates and domain events)
  • Core domain layer is surrounded by the UI/Application layer and Infrastructure layer
  • UI/Application layer (UI and application service facade with messaging, JSON, XML capabilities, session, etc.)
  • Infrastructure layer (persistence, file system, network, mail, logging, etc.)

5. Entities:

  • Live longer than the application, should endure restarts, and are persisted and read from data sources (DB, file system, network, etc.)
  • Have an id (preferably a GUID rather than a DB generated int because business transactions do not rely on persistence, can be persisted after other operations carried out in model's behavior)
  • Have entity semantics (equality and GetHashCode() defined by class name + id)
  • Behavior in an entity mostly orchestrates value objects for a use case
  • Entity class should not have public property setters, setting a property should be a behavior method
  • Entities should not have bidirectional relations (depending on the bounded context, either an egg can have a chicken or a chicken can have eggs, but not both)
  • Entity relations should not reflect the complete set of DB foreign key relationships, should be bare down to the minimum for performing the behavior inside the bounded context
  • Entity relations should not hold a reference to another entity class, it can only keep the id of another entity
  • If a business transaction needs a reference to other entities in relation, aggregates should be used instead (aggregates can hold a reference to other aggregate roots, which are entity classes by definition)

6. Value objects:

  • Are only identified by their values, not by their ids (for example money is a value object as long as we are not tracking individual banknotes, if we need to track individual banknotes then it should be a banknote entity)
  • Can be used to measure or describe things (name, description, amount, height, date, time, range, address, etc.)
  • You can combine other value types that usually go together into a new value object type, like address (city, street, country, postal code) or ...range, or ...type
  • Prefer to put the behavior on value objects rather than on entities because value objects are immutable and do not have side effects (like changing their state or changing the state of any entity)
  • Can be part of an entity
  • Have value semantics (equality and GetHashCode() defined by property values)
  • Should be immutable, behaviors should not change the state of a value object, but can rather create a new value object (should act similar to C# strings, structs, ints, and other value types)
  • Can be persisted but only as part of an entity, not individually

7. Factories:

  • Create, build aggregates and entities:
  • Static Create...() factory method on a model class is used to guard against the construction of an invalid or incomplete model
  • The model class should not have a public default constructor (however if it is to be persisted, for Entity Framework to work, it can have a protected or private default constructor)

8. Aggregates:

  • Encapsulate and are composed of entity classes and value objects that change together in a business transaction
  • Aggregates are a transactional graph of model objects
  • Aggregate root should be an entity, an aggregate can even be a single entity
  • Aggregate can keep a reference to other aggregate roots, but not to other entity classes which are not aggregate roots themselves
  • Aggregate should not keep a reference to other aggregate root entity classes if those other entities do not change together with this aggregate root entity
  • Aggregate can also keep the id of another entity, but keeping too many foreign key ids is a code smell (why?)
  • If deleting an entity has a cascade effect on the other entities referenced by class in the object graph, these entities are part of the same aggregate, if not, they should not be inside this aggregate

9. Repositories:

  • Persist and read aggregates to/from DB or file system
  • Should have an interface close to a collection but should allow only the necessary operations needed for this aggregate (for example an aggregate might not need to be allowed to get updated or deleted)
  • Should not be generic (should be specific for the aggregate type)
  • Can have specific query methods if needed (like FindByName() etc.)
  • Do not use lazy loading, instead use eager loading (use Include(...) in Entity Framework), else you can face "N+1 problem"s and excessive number of queries sent to DB
  • Can have specific methods that only load some of the columns from a table
  • Repository add/update/remove operation should commit to DB by itself (call Entity Framework ...Context.SaveChanges() at the end), because aggregate operations should be ACID transactions
  • Repository interface sits inside Core domain layer, but implementations are inside Infrastructure layer
  • Repositories are not used inside the domain models (entities, value objects, aggregates)

10. Shared kernel:

  • Is where cross-cutting concerns or common types shared by all bounded contexts sit (like entity abstract base type, value object abstract base type, common value objects, authorization, etc.)

11. Domain events:

  • Can be raised when a state change occurs in an entity
  • Decouple models from each other
  • Only used when an event needs to be handled inside a different model than the one raising this event, or handled inside a domain service or even an application service
  • Are immutable classes, that represent past, named in the past tense, and cannot change (...Changed, ...Happened, etc.)
  • Should include the time that this event was raised, as well as any other useful info for handling the event, as well as the id of the entity which raised the event
  • Should not have behavior
  • Domain events are subscribed to with a callback (lambda), or using pub sub interfaces, on a singleton or static event message bus
  • Domain events implemented this way can be subscribed to and handled in the aggregate root of the entity which raised the event, or in domain services, or even in UI/Application layer
  • Domain events are raised synchronously, if an asynchronous task needs to be carried out, it can be done inside the event handler (async-await pattern)
  • Outside applications can also be triggered by using a message queue or an enterprise service bus (ESB) inside the domain event handler

12. Anti-corruption layer:

  • Used to translate models from outside systems or legacy apps to models inside the bounded context and vice versa, and also to ease the communication with legacy services
  • Can use service facades and model adapters.

Questions & Issues

Welcome to everyone asking questions, requesting features or reporting bugs.

License

MIT licensed.

You might also like...

A Javascript lib about complex

RealComplex.js 一个关于复数的Javascript库 A Javascript lib about complex How to use it? 使用教程 导入与实例化 import { Complex } from './Complex.js'; let x = new Comple

Feb 9, 2022

FormGear is a framework engine for dynamic form creation and complex form processing and validation for data collection.

FormGear is a framework engine for dynamic form creation and complex form processing and validation for data collection.

FormGear is a framework engine for dynamic form creation and complex form processing and validation for data collection. It is designed to work across

Dec 27, 2022

high performance、complex interaction table

功能描述 1、高性能、满足复杂交互的编辑表格 2、基于: antd4(https://ant.design/index-cn) ag-grid(https://www.ag-grid.com/) 3、基于原生ag-grid 的API进行封装 一、主要功能 将按下列顺序逐步迭代 1、通用编辑功能 🚧

Feb 15, 2022

🐻 Trying out the bear necessities for complex state management.

🐻 Zustand Demos My practice repository for the Zustand library--the bear necessities for complex state management. You can find some examples of how

Jul 2, 2022

Start building admin tools on Slack without going into complex slack syntax and flows.

Start building admin tools on Slack without going into complex slack syntax and flows.

Slackmin Slackmin helps in easy integration with slack to use slash commands, interactive components, format and send messages, design and use modals.

Jan 2, 2023

io-ts Typed Event Bus for the runtime of your Node.js application. A core for any event-driven architecture based app.

Typed Event Bus Based on io-ts types, this bus provides a handy interface to publish and consume events in the current runtime of the Node.js process.

May 23, 2022

An application to map out game reserves using aerial photography, intelligent image stitching and AI driven recognition focus.

Map Out Game Reserves Using Aerial Photographs An application to map out game reserves using aerial photography, intelligent image stitching and AI dr

Sep 29, 2022

Calculate the price range for property advertised on Domain and Real Estate.

Calculate the price range for property advertised on Domain and Real Estate.

Property Seeker Calculate the price range for property advertised on Domain and Real Estate. Install Chrome Firefox Edge Privacy All searches are perf

Dec 27, 2022

... a contemporary perspective on how to integrate B2C Commerce and the Salesforce Customer 360 Platform to power frictionless customer experiences in the B2C domain.

Salesforce B2C Commerce / Customer 360 Platform Integration Introduction Salesforce B2C Commerce / CRM Sync is an enablement solution designed by Sale

Dec 9, 2022
Comments
  • Request for ImageUrlValueObject

    Request for ImageUrlValueObject

    Anh nghĩ ngoài UrlValueObject thì cũng cần ImageUrlValue Object cái này khác ở chỗ nó có extension jpg | png | gif | svg cái extension này cho override được cũng tốt

    enhancement 
    opened by minhtrongtgm 1
  • IdValueObject có lỗi runtime

    IdValueObject có lỗi runtime

    Hình như cái lib có bug run time đấy Văn ơi

    cái mấy cái Id valueobject ấy

    cái dòng outerGroupId = new GroupId(community.groupId.value); image

    khi code thì không báo lỗi

    nhưng khi start lên và debug thì cái groupId nó không phải là 1 class ValueObject mà nó chỉ là 1 plain object kiểu { props: { value: 'abc' } }

    7:08 AM

    thế nên community.groupId.value bị undefine

    bug 
    opened by minhtrongtgm 0
Releases(v0.1.5-anpha)
Owner
null
This is another Express + TypeScript + DDD (Domain Driven Design patterns) + IoC/DI (Inversion of control and Dependency injection) + Primsa ORM + API REST boilerplate.

Express-TS-DDD REST API This is another Express + TypeScript + DDD (Domain Driven Design patterns) + IoC/DI (Inversion of control and Dependency injec

J.D. 6 Nov 3, 2022
Deploy a multi-account cloud foundation to support highly-regulated workloads and complex compliance requirements.

Landing Zone Accelerator on AWS The Landing Zone Accelerator on AWS solution helps you quickly deploy a secure, resilient, scalable, and fully automat

Amazon Web Services - Labs 130 Dec 29, 2022
'event-driven' library aims to simplify building backends in an event driven style

'event-driven' library aims to simplify building backends in an event driven style(event driven architecture). For message broker, light weight Redis Stream is used and for event store, the well known NoSQL database, MongoDB, is used.

Sihoon Kim 11 Jan 4, 2023
Use Cloudflare Pages Functions as a reverse proxy with custom domain support.

cf-page-func-proxy Use Cloudflare Pages Functions as a reverse proxy with custom domain support. Getting Start 1.下载或是Fork本仓库 2.修改_worker.js中的url.hostn

null 121 Dec 23, 2022
A tiny foundation that providing nested state-based routing for complex web application.

StateMan stateman: A tiny foundation that provides nested state-based routing for complex web applications. stateman is highly inspired by ui-router;

ZhengHaibo 390 Dec 20, 2022
HackFest is a 36-hour long hackathon wherein you have to put on your hacker hats and build anything that falls in either or both the domain of full-stack web development

HackFest is a 36-hour long hackathon wherein you have to put on your hacker hats and build anything that falls in either or both the domain of full-stack web development (the stack we learn in full-stack web developer roadmap on codedamn).

Shivam Kumar 2 Jun 6, 2022
Package fetcher is a bot messenger which gather npm packages by uploading either a json file (package.json) or a picture representing package.json. To continue...

package-fetcher Ce projet contient un boilerplate pour un bot messenger et l'executable Windows ngrok qui va permettre de créer un tunnel https pour c

AILI Fida Aliotti Christino 2 Mar 29, 2022
Query for CSS brower support data, combined from caniuse and MDN, including version support started and global support percentages.

css-browser-support Query for CSS browser support data, combined from caniuse and MDN, including version support started and global support percentage

Stephanie Eckles 65 Nov 2, 2022
An AWS Cloud Native application using CDK that defines a Serverless Event Driven application for interacting with Twitter and utilising Machine Learning / AI as a Service.

AWS Serverless Event Driven Twitter Bot An AWS Cloud Native application using CDK (Written in TypeScript) that defines a Serverless Event Driven appli

null 4 Dec 18, 2022
Zemi is data-driven and reverse-routing library for Express. It provides out-of-the-box OpenAPI support, allowing you to specify and autogenerate an OpenAPI spec.

zemi zemi is a data-driven routing library for Express, built with Typescript. Features: optional, out-of-the-box support for OpenAPI reverse-routing

Yoaquim Cintrón 5 Jul 23, 2022