Full Stack Web Application Quickstart using DDD (Node version)
Overview
This is a working (see demo), DDD-inspired web application sample configuration, written in TypeScript using common packages (e.g Node.js, Express.js, Mocha, React), that can be used to start a new project or simply to anchor a discussion (NOTE: The demo can take some time to come up as this is on the free-tier of the Azure App Services). There is supplemental documentation on how to deploy this to Azure using offerings such as Azure Web App for Containers, Azure Container Registry, and Azure AD as an identity provider for authentication .
Architecture
At a high-level, the major components of this architecture are simply as follows.
- model (core, server, client) - See below
- server (web server) - Concerned with handling all concerns as they pertain to the protocols such as HTTP and WebSockets using libraries like Express.js and socket.io. Data from the channels is translated to calls to model.server for processing.
- ui (browser) - Visualization of entities expressed in model.core.
This architecture is domain-driven by virtue of the model set of packages that can be found under the model folder. A description of each of these packages is below.
- core - Core business logic of an application containing entities, relationships, object graph navigation, serializable structures (state), business rules, calculations, reports, etc. In practice, this module is often further decomposed between entity and query (reporting) concerns. The concepts of interest that connect the business meaning and purpose to the source code is encapsulated here. All other modules in the application can depend on this one.
- server - Depends on model/core and is the main dependency of the API server though its clients could be other things that run on a server such as a daemon. One of the main functions of this module is its data access layer which hydrates states defined model/core from various data sources (e.g. document and/or relational databases, REST APIs, file system, memory, etc). Its general usage is in a server context and thus the name "server".
- client - Depends on model/core and is a dependency of UI. This module hydrates model core entities from data sources such as REST APIs and/or web sockets exposed by the API server. The intent is for all browser networking to be done here and hidden from the rest of the application. Its general usage is to run in a client context such as a browser thus the name "client". The module is part of the model because from the client code perspective this is module is the gateway to model functionality. In a nutshell, this is strongly typed API expressed in the types from model.core that makes working with the REST or web sockets easier. This is similar in theme to SDK client libraries such as those for Azure which make working with various cloud services easier.
Some benefits, among many, of this approach are as follows:
- Reuse - Code, specifically model.core, allowed to be used by any other module. What is emphasized in this setup is the ability to run the same business logic code in the user-agent and on the server (Node.js). A calculation, for example, can be done on either side when both have the same model/core code and data without the need for either to talk to each other. When reuse becomes high, cost tends to trend down significantly.
- Testability - The first calling client to logic isolated to the model set of projects is a test suite like Mocha. There should be no need to run the application to assert on the correctness of the modules or to have to account for a framework in the way when testing.
Tooling
- Node v18.16.1 - Its recommended to use Node Version Manager (Windows, Linux)
- PowerShell Core v7.3 - The execution policy should be set to RemoteSigned for the current user scope (Windows, Linux)
Installation
> git clone https://github.com/strisys/web-application-quickstart-node.git
> cd web-application-quickstart-node/scripts
> pwsh ./build-run-local.ps1
See the docs for running on containers in combination with Azure.
Workflow
Its necessary to mention a word about developer workflow when using Visual Studio Code as switching between projects will be an frequent occurrence. The recommended extension for this purpose is Project Manager. Please refer to its documentation for configuration.