Distributed Design
This repository demonstrates a minimal .NET microservice framework (each microservice is referred to as a node) that takes as few external dependencies as possible. In addition to standard data retrieval and mutations, this architecture also focuses on easily enabling cross-node communication and distributed real time data synchronization. SQL Server serves as the underlying storage mechanism through Entity Framework. SignalR is used for real time data synchronization.
Terminology
This project uses the following terminology to describe different facets of its infrastructure:
Term | Definition | Example |
---|---|---|
API | A .NET Web API project that provides a configuration point and establishes HTTP and Web Socket endpoints for a Node. | Proposals.Api |
App | A client that interfaces with one or more Nodes. | proposals |
Command | A Service that defines user-driven public data mutation methods. | ProposalCommand |
Contract | An Entity that facilitates interaction between Nodes. A Contract can be thought of as a public Entity. | Package |
Entity | A data model represented by an underlying store table that encapsulates an aspect of the associated Node domain. | Proposal |
EventHub | A strongly-typed SignalR Hub that broadcasts Entity-based mutation events. |
|
EventListener | A SignalR client that facilitates reacting to Contract-based mutation events broadcast by an EventHub. |
|
Gateway | The publicly-exposed API interface defined by a Node that facilitates cross-node interaction. |
|
Hook | An asynchronous delegate function that allows logic to be executed at critical moments within a Command action. | |
Node | A microservice backend that encapsulates a single micro domain. This term was selected in place of Service to avoid confusion. Service is an overloaded term that already carries a different definition in this architecture. | proposals |
Query | A Service that facilitates retrieval of Entity data. | ProposalQuery |
Saga | A Service that defines system-driven private data mutation methods; they isolate reactionary logic for determining how to handle effects of mutations triggered through external node Events. Typically, a Saga is defined when you want to adjust internal Entities in response to changes in associated external Contracts. | PackageSaga |
Service | A class that exposes functionality and is registered with the .NET Dependency Injection service container. Query, Command, EventListener, and Saga are all examples of services with a targeted intent. | GatewayService |
Directory Structure
The layout of the repository is expressed as follows:
- .devcontainer - Dev Container configuration for running this project in GitHub Codespaces.
- .github/workflows - GitHub Actions workflows for deploying docs.
- .vscode - Tasks and Debug configurations for VS Code.
- apps - All app-related infrastructure.
- libs - Contains local npm libraries that define common infrastructure for app development.
- contracts - Libraries that define publicly available entity classes and their underlying infrastructure.
- core - Library that contains all of the core infrastructure for building apps that interface with nodes.
- distributed - Angular workspace that defines the
@distributed/toolkit
library. Contains Angular-specific infrastructure that can be shared between Angular apps.
- proposals - Angular app interface for the
proposals
node. - workflows - Angular app interface for the
workflows
node.
- libs - Contains local npm libraries that define common infrastructure for app development.
- docs - Repository documentation, hosted at https://jaimestill.github.io/distributed-design.
- nodes - All node-related infrastructure.
- contracts - Projects that define publicly available entity classes and their underlying infrastructure.
- core - Class library that contains all of the core infrastructure for building out a node.
- Controllers - Abstract Controller definitions.
- Data - Infrastructure for building out Entity Framework Core related features.
- Entities - Core classes and interfaces for building entity classes for a node.
- Extensions - Extension methods that provide enhanced functionality and / or standardizes node configuration.
- Gateway - Infrastructure for building a gateway within a node.
- Messages - Return types that wrap a data type with metadata about the results of the operation that was performed.
- Middleware - Contains node specific middleware infrastructure.
- Services - Core classes and interfaces for building command, query, event, and saga services for a node.
- Events - Infrastructure for building SignalR-based event hubs and clients.
- proposals - A simple demonstration node that facilitates the development of proposals.
- workflows - A simple demonstration node that facilitates the staffing of packages through pre-defined workflows. Packages are generated from external services through the
Package
contract via theWorkflowsGateway
.
- scripts - PowerShell scripts that facilitate management of Azure cloud deployment (see deploy-azure.ps1) and local npm libraries (see clean-apps.ps1).
deploy.json
- Contains metadata for simplifying Azure cloud deployment.