Solution scaffolding to quickly bootstrap an API.
The idea is to provide a set of ready-to-use projects with code dependencies and examples. It is especilly useful and time saving when you already know the api is not just a CRUD component but but a component that will grow fast with complex domain code.
In DDD, the idea is to have 1 BC per service, but if you are challenging boundaries and not sure yet, it is preferable to keep all your code base in the same service. You can easily adjust this project to work with multiple bounded context.
- Hexagonal architecture is order to decouple domain code from infrastructure purpose
- Command and Query Segregation (CQS) using Mediator to separate write code from read code, avoiding to mix up models
- In memory Event driven architecture, in order to transform procedural code to reactive programming by chaining side effects based on (domain) events
- Domain Driven Design to express domain with tactical patterns like aggregate, entities, value object, domain event, ...
- Repository pattern
- Url versioning to avoid breaking changes on api evolution
- Swagger to document and explore which end points are available
- Problem details to normalize error management
- Health check to provide routes exposing application state (/hc, /liveness)
- Entity framework to simplify database read and write
- TransactionScope to handle domain transaction by code, not by database
- Database migration with FluentMigrator in order to migrate the database easily with fluent code
- Unit tests with xUnit & FluentAssertions
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void Renaming_a_customer_requires_a_non_empty_first_name(string emptyFirstName)
{
Customer customer = A.Customer;
var action = () => customer.Rename(emptyFirstName, "some last name");
action
.Should()
.Throw<ArgumentException>();
}
- Acceptance tests using Specflow on top of api, in order to have human readable specifications
Scenario: Registering a new customer lists it
When I register the following new customer
| First name | Last name |
| John | Doe |
Then the customer list is
| Full name |
| John Doe |
- Integration by only annotating
@Integration
some of acceptance tests
@Integration
Scenario: Renaming a customer has his name well updated in the list
When I rename the customer "John Doe" to "Albert Rose"
Then the "John Doe" customer is now listed with full name "Albert Rose"
- Containerization with Dockerfile & Docker compose
- Basic github action to trigger CI dotnet.yml
- Open telemetry [todo] to normalize logs, traces and metrics
- .net Feature management in order to easily and dynamically activate or deactivate features from configuration.