A microservice should be designed in layers with each performing an area of concern for the architecture.
Our platform provides a layered design for the operation of the service as well as the release of a service.
This layered design allow extensibility at each point, allowing you to add new functionality and methods.
API Layered Design
We provide a CRUD-based, repository design at the heart of our platform.
This enables standardization and governance within each service that is developed in the platform.
Errors trapped at any layer can provide human-readable output response that will be returned to the caller.
A call is initially received at the API Controller level and the request is passed using our request and response objects through the layered design.
The call flow top-to-bottom through the following list:
- IApiClient<DataTransferObject> - Provides for the client to call the microservice.
- IApiController<DataTransferObject> - Initial API call entrance for the microservice. Responds with an IActionResult
- IApiService<DomainObject, DataTransferObject> - Provides the standard API logic and domain API eventing
- IDomainRepository<DomainObject> - Provides standard CRUD repository methods and domain repository eventing
- IStorageRepository<DomainObject> - Provides standard CRUD repository methods and domain storage eventing for a particular storage provider
Repository Layered Design
Each layer performs logic based on its area of concern, while also raising Events, sending Broadcasts and/or invoking Processes.
- IDomainRepository - This upper layer defines the required operations for a domain object exposed via the API. The IDomainRepository flows all of its calls down to the IStorageRepository.
- IRepository - This middle layer defines the required operations for a domain object that extend upward, through the API, and downward, through the storage provider. This layer contains no implementation and is strictly used as a design artifact to enforce cohesion above and below.
- IStorageRepository - This lower layer defines the required operations for a domain object exposed via a Storage Provider. Further requirements can be enforced on the model by the underlying storage engine capabilities.
This is further broken down by each supported storage provider.
- AzureDataTables- Exposes the IAzureDataTablesDomainObject and the IAzureDataTablesStorageRepository implementations.
- EntityFrameworkCore- Exposes the IEntityFrameworkCoreDomainObject and the IEntityFrameworkCoreStorageRepository implementations.
- MongoDb - Exposes the IMongoDbDomainObject and the IMongoDbStorageRepository implementations.
NuGet Release Package Layered Design
When each new Service Brick is released, the following packages are created with it.
All packages reference the package directly above them.
- ServiceBrick.[Module].Api - This package contains broadcasts, clients, events, DTOs, interfaces and processes exposed and used within the domain.
This is the top-most library that all lower packages reference.
- ServiceBrick.[Module].Api.Controller - This package contains all the controller implementations for the service that exposes its API.
If you want the functionality of the service but don't want to expose the API, don't include this package.
- ServiceBrick.[Module] - This package contains all common code and integration used in the service.
- Storage Providers
- ServiceBrick.[Module].AzureDataTable - This package contains the Azure Data Tables storage provider implementation.
- ServiceBrick.[Module].EntityFrameworkCore - This package contains the EntityFrameworkCore storage provider implementation.
- ServiceBrick.[Module].MongoDb - This package contains the MongoDB storage provider implementation.