Griffin
Reusable .NET building blocks for production-ready web services.
What Griffin Provides
- CQRS contracts and domain model primitives for commands, queries, entities, aggregates, events, and pagination.
- Vertical-slice-friendly ASP.NET Core conventions for minimal endpoints, API versioning, correlation IDs, and service registration.
- Cross-cutting MediatR behaviors for validation, logging, transactions, caching, and cache invalidation.
- PostgreSQL and Entity Framework Core helpers for snake_case naming, migrations, seeding, soft-delete filters, and resilient transactions.
- MongoDB repository and unit-of-work abstractions for read models and document persistence.
- EventStoreDB integration with projections, subscriptions, event mapping, and event-sourced aggregates.
- Wolverine integration for messaging, durable workflows, local queues, and transport-backed application services.
- JWT authentication, OpenAPI and Scalar documentation, health checks, Problem Details, and OpenTelemetry.
- Shared testing infrastructure and utilities for integration tests and container-backed dependencies.
Goals
Griffin aims to make the first version of a service easier to assemble without forcing every service into the same architecture. Its main goals are:
- Keep domain and application contracts independent from transport and persistence details.
- Make vertical slices easy to register, validate, observe, and test.
- Provide consistent defaults for common ASP.NET Core concerns.
- Support both synchronous request handling and durable asynchronous workflows.
- Keep infrastructure integrations optional and separated by project.
Technology
Griffin builds on established .NET libraries rather than replacing them:
| Area | Technologies |
|---|---|
| Runtime and web | .NET 10 , ASP.NET Core, Minimal APIs |
| Application | MediatR , FluentValidation, Scrutor, Mapster |
| Data | Entity Framework Core , PostgreSQL, MongoDB , EventStoreDB |
| Messaging | Wolverine , RabbitMQ |
| Operations | OpenTelemetry, health checks, Problem Details, Polly |
| API tooling | ASP.NET API Versioning, OpenAPI, Swagger UI, Scalar |
| Testing | xUnit, Testcontainers, Respawn, NSubstitute |
When to Use Griffin
Griffin is a good fit when several services share the same web and application conventions, especially when a system needs CQRS, PostgreSQL-backed writes, MongoDB read models, event sourcing, durable messaging, or consistent observability.
It is intentionally not a full application template. A small CRUD API may need only Griffin.Core, Griffin.Web, and one persistence module. Avoid referencing the umbrella project when a narrower project reference is enough.
Requirements
- .NET 10 SDK
- PostgreSQL, MongoDB, EventStoreDB, or a message broker only when the corresponding module is used
- Docker is useful for integration tests and local infrastructure
Installation
Each Griffin module is published as an independent NuGet package. All modules use the same version from each GitHub release. Install only the packages your service needs:
dotnet add package Griffin.Core
dotnet add package Griffin.Web
dotnet add package Griffin.EFCoreWhen a GitHub release is published, the publish workflow pushes every library package to NuGet.org using that release tag’s version. The repository requires an Actions secret named NUGET_API_KEY containing a NuGet.org API key with package push permissions.
Quick Start
The following example shows the usual ASP.NET Core composition. Add only the integrations required by your service.
using Griffin.EFCore;
using Griffin.Jwt;
using Griffin.OpenApi;
using Griffin.ProblemDetails;
using Griffin.Web;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCustomVersioning();
builder.Services.AddAspnetOpenApi();
builder.Services.AddJwt();
builder.Services.AddCustomHealthCheck();
builder.AddMinimalEndpoints();
// TContext must inherit DbContext and implement IDbContext.
builder.AddCustomDbContext<ApplicationDbContext>("database");
var app = builder.Build();
app.UseCorrelationId();
app.UseCustomProblemDetails();
app.UseAuthentication();
app.UseAuthorization();
app.MapMinimalEndpoints();
app.UseAspnetOpenApi();
app.UseCustomHealthCheck();
app.UseMigration<ApplicationDbContext>();
app.Run();Modules
| Project | Purpose |
|---|---|
Griffin.Core | Domain, CQRS, events, exceptions, and pagination contracts |
Griffin.Web | Minimal endpoints, API versioning, options, correlation IDs, and web helpers |
Griffin.EFCore | EF Core and PostgreSQL context, migration, seeding, and transaction helpers |
Griffin.Mongo | MongoDB contexts, repositories, and unit-of-work abstractions |
Griffin.EventStoreDB | EventStoreDB configuration, projections, subscriptions, and repositories |
Griffin.Wolverine | Wolverine messaging and application integration |
Griffin.Caching | EasyCaching MediatR behaviors and cache contracts |
Griffin.Validation | FluentValidation MediatR behavior |
Griffin.Log | Logging behavior for application requests |
Griffin.Polly | Resilience and HTTP client helpers |
Griffin.Jwt | JWT bearer authentication and authorization policies |
Griffin.OpenApi | OpenAPI, Swagger UI, and Scalar setup |
Griffin.OpenTelemetryCollector | Logs, metrics, traces, and diagnostics setup |
Griffin.HealthCheck | Health and liveness endpoint configuration |
Griffin.ProblemDetails | Consistent HTTP exception and status-code responses |
Griffin.Mapster | Mapster registration and assembly scanning |
Griffin.TestBase | Shared test fixtures and integration-test support |
Griffin.Utils | General-purpose shared utilities |
Each library declares the NuGet packages it uses directly. Project references connect library APIs and are kept local to the modules that consume them.
Configuration
Options are bound by type name in the standard .NET configuration system. A typical service keeps settings in appsettings.json or environment variables:
{
"Jwt": {
"Authority": "https://identity.example.com",
"Audience": "orders-api"
},
"PostgresOptions": {
"ConnectionString": "Host=localhost;Database=orders;Username=postgres;Password=postgres"
}
}Prefer environment variables or a secret store for credentials in deployed environments. Do not commit connection strings, signing keys, or broker credentials.
Development
Documentation
The live documentation uses Nextra and GitHub Pages. Its pages are generated from this README, docs/how-it-works.md, CONTRIBUTION.md, and the per-module guides under docs/modules/ before every build. Each Griffin package has its own guide covering installation, registration, configuration, and usage.
To preview locally with Node.js 22 or newer:
cd docs/site
npm ci
npm run devOpen http://localhost:3000. Run npm run build to export the static site and Pagefind search index to docs/site/out. Restart the dev server after editing source Markdown to regenerate pages. Search requires a production build served over HTTP; it is not indexed by the dev server.
For first deployment, select Settings > Pages > Build and deployment > Source > GitHub Actions in the GitHub repository. The Documentation workflow validates pull requests and deploys updates from main; it can also be run manually. The live URL becomes available after the first successful deployment.
Library Build
Restore and build the complete library from the repository root:
dotnet restore griffin.slnx
dotnet build griffin.slnxThere is no test project in the solution currently. Griffin.TestBase provides shared fixtures and Testcontainers support for downstream integration tests.
Format changed C# files with the normal .NET formatter when needed:
dotnet format --no-restoreWhen developing integrations locally, Docker containers are recommended for PostgreSQL, MongoDB, EventStoreDB, and RabbitMQ. The test support projects include Testcontainers dependencies for repeatable integration environments.
Support
If you like my work, feel free to:
- ⭐ this repository. And we will be happy together :)
Thanks a bunch for supporting me!
Contribution
Thanks to all contributors , you’re awesome and this wouldn’t be possible without you! The goal is to build a categorized, community-driven collection of very well-known resources.
Please follow this contribution guideline to submit a pull request or create the issue.
License
Griffin is available under the MIT License .