WebApiSkeleton 1.1.1
dotnet new install WebApiSkeleton::1.1.1
WebApiSkeleton
WebApiSkeleton
is MediatR-based project template to develop any types of applications based on ASP.NET Core. The
template allows to quickly start the developing process and has most of frequently required features implemented.
Contents
- Description
- Module repositories
- Key principles
- Project structure
WebApiSkeletonTemplate.API
WebApiSkeletonTemplate.Domain
WebApiSkeletonTemplate.Contracts
WebApiSkeletonTemplate.ContractValidation
WebApiSkeletonTemplate.Database
WebApiSkeletonTemplate.Migrator
WebApiSkeletonTemplate.DistributedLockExtensions
WebApiSkeletonTemplate.IdentityMigrations
WebApiSkeletonTemplate.Ping
- Infrastructure dependencies
- Example
Description
The template uses MediatR
across all the packages (except for abstractions and Tasks) to reduce boilerplate code,
increase the developing speed and make code more clear by strictly following Single Responsibility Principle.
These advances are achieved by using Pipeline behaviors
that handle most frequent scenarios, such as validation,
authentication, authorization and usage of database transactions.
Module repositories
There are several modules added in template that have their own documentation. It is highly recommended to get known with them.
WebApiSkeleton.Security
WebApiSkeleton.FileSystem
WebApiSkeleton.Search
WebApiSkeleton.Utilities
WebApiSkeleton.Tasks
Key principles
There are feature interfaces defined in WebApiSkeleton.Contracts.Base
package that define the behavior of MediatR
requests (contracts).
Result type
One of most used interfaces is IResultTypeResponseRequest<T>
. Requests that implement this interface are returning
the Result<A>
struct
from LangudageExt.Core
package. Result
is a functional-style struct that can have only 2 states: faulted or success.
Faulted contract result contains an exception that defines the reason request is faulted. Success request contains the
object of type defined as a generic argument of Result<A>
.
This struct is used for validation and authorization in pipeline behaviors. Faulted result means the validation failure or authorization issues for user, executing a request.
Pipeline behavior registration
It is mandatory to mind the order of pipeline behaviors registered in DI container as they are executed in the order they were added to DI. To prevent unexpected application behavior and make it more flexible, the registering process for most pipeline behaviors is leftover to user. Therefore, there is recommended order for built-in template pipeline behaviors to optimize the performance and make handling process more clear and obvious:
CommandLoggingBehavior
- command execution logging;PermissionBehavior
- defined inWebApiSkeleton.Security
and is used to handle authentication and authorization;ValidationBehavior
- defined inWebApiSkeleton.Contracts.Validation
and is used to validate incoming requests usingFluentValidation
;TransactionBehavior
- automatically emits a request-scope transaction that is commited after the handling process is successful. Only works for request that are implementingITransactRequest
feature interface;DistributedLockPipelineBehavior
- catches theDistributedLockException
and returns it as aResult
if possible, otherwise throws the exception further.
PermissionBehavior
and ValidationBehavior
are added separately for any request that is requiring such functionality
because of Result<A>
returning type. Although, there are extension methods on IServiceCollection
that allow to add
them automatically from needed assembly or by creating them from the request type. Details on this behavior registering
can be found in respective repositories.
All other behaviors are registered once for all requests by using
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(CommandLoggingBehavior<,>));
CQRS
It is recommended to follow CQRS (Command-Query Responsibility Separation) principles using this template. This way, contracts of template can be divided into two types:
- Commands are contracts that can make changes on data or modify state of application. If command is using database it
is recommended to use request-scope transaction and EF
Core
ApplicationContext
to perform actions. Repository should inherit fromCommandRepositoryBase
; - Queries are contracts that do not affect the state of application and just read information from database or some
other source. If query uses database it is recommended to use
ConnectionProvider
(default isNpgsqlConnectionProvider
for PostgreSQL) to getIDbConnection
and generate a required SQL query. Transaction use is not required in these contracts but can be used in specific cases. It is not forbidden to injectApplcationContext
in query repositories for simple queries, but it is highly recommended not to perform any non-readonly DDL actions. Repository should inherit fromQueryRepositoryBase
. It contains useful methods for SQL generation fromWebApiSkeleton.Search
models.
Project structure
WebApiSkeletonTemplate.API
A presentation-layer project containing the Web API. It references all other projects and uses all of
the WebApiSkeleton
dependencies. The module configuration is recommended to be done in this project to simplify the
structure of application;
WebApiSkeletonTemplate.Domain
Core project that should contain all application-wide model definitions (e.g. background tasks or business entities) and dependencies (e.g. functional models, useful extension methods);
WebApiSkeletonTemplate.Contracts
Project that contains all MediatR
request related models (input/output models that are not defined in domain or
implementing different abstaction level logic, events, application-wide pipeline behaviors, etc.) and contracts
themselves;
WebApiSkeletonTemplate.ContractValidation
Project that contains FluentValidator
validators for contracts that implement IValidatableRequest
. Error messages
can be defined in this project, too;
WebApiSkeletonTemplate.Database
Contains all database-specific dependencies, such as Entity Framework Core and Dapper. Default provider is PostgreSQL, but can be changed if needed. Contains repositories that provide data to implementation modules;
WebApiSkeletonTemplate.Migrator
A wrap around FluentMigrator
that contains the hosted service that applies migrations on application startup. Also
defines useful extension methods that are not defined in FluentMigrator
by default;
WebApiSkeletonTemplate.DistributedLockExtensions
Contains just pipeline behavior for distribute-locked requests. Can be modified to add functionality for distributed locking in application;
WebApiSkeletonTemplate.IdentityMigrations
Contains migrations for WebApiSkeleton.Security
module but can be deleted if unneeded (different schema apply method
used). Migrations are generated by using dotnet ef
tool Not generated with IdentityMigrations false
template
parameter;
WebApiSkeletonTemplate.Ping
Only contains example implementation module. Should be deleted along with other example models when using template in
application. Not generated with Example false
template parameter.
Infrastructure dependencies
All infrastructure dependencies can be easily set up by using docker compose
.
Redis
Redis in-memory database is used across whole template. By default, all distributed locks and semaphores are applied
using Redis
. WebApiSkeleton.Security
uses Redis for caching permissions and user roles. WebApiSkeleton.Tasks
persists queue state in Redis.
Application stability tested with Redis 7.0, lower versions are not guaranteed to not break the behavior of modules functionality.
PostgreSQL
The default SQL provider for the template and WebApiSkeleton.Security
is PostgreSQL. Template provider can be changed
to any other (but SqlServer
is not recommended to due to lack of deferred foreign key checks to implement request-wide
transactions). WebApiSkeleton.Security
provider can only be changed to Sqlite
if needed.
Application stability tested with PostgreSQL 15.0, lower versions are not guaranteed to not break the behavior of modules functionality.
RabbitMQ
RabbitMQ is used as one of optional message brokers for WebApiSkeleton.Tasks
distributed queue.
Application stability tested with RabbitMQ 13.3, lower versions are not guaranteed to not break the behavior of distributed queue module functionality.
Minio
Minio is used as a default implementation of file storage in WebApiSkeleton.FileSystem
module.
Example
Example usage is supplied with template in WebApiSkeletonTemplate.Ping
implementation module. Other project also contain classes to implement an example.
NOTE: example generation can be disabled in template settings
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
- Fixed preprocessor statements for parameter configuration
- Upgraded WebApiSkeleton.FileSystem.MinIO to 1.1.3 version