# gmrodriguez12/webapi-onion architecture

> Architecture diagram of the GitHub repository gmrodriguez12/webapi-onion, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-10). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/gmrodriguez12/webapi-onion
- Repository: https://github.com/gmrodriguez12/webapi-onion

## Overview

This is an Onion-architecture .NET 6 Web API template for CRUD operations on AdventureWorks products. A client sends product requests to the versioned API; the controller dispatches MediatR commands or queries, whose handlers use repository abstractions and return response DTOs. Listing adds subcategory filtering and pagination. The README documents pipeline validation, FluentValidation, AutoMapper, CQRS, MediatR, Ardalis.Specification, and EF Core database-first mapping. The graph shows documented and indexed relationships; unsampled validator wiring and some persistence details are not asserted.

Main entry points: [`WebAPI/Controllers/v1/ProductController.cs`](https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Controllers/v1/ProductController.cs) (Product controller), [`Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs) (List products), [`Application/Features/Products/Commands`](https://github.com/gmrodriguez12/webapi-onion/tree/master/Application/Features/Products/Commands) (Product commands), [`Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs`](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs) (Get product)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["HTTP API"]
  node_controller["Product controller"]
  node_base["MediatR access"]
  node_errors["Error middleware"]
end

subgraph group_application["Application workflow"]
  node_commands["Product commands"]
  node_getbyid["Get product"]
  node_getall["List products"]
  node_validation["Validation behavior"]
  node_appregistration["Application registration"]
  node_mapping["Product mapping<br/>[GeneralProfile.cs]"]
  node_dto["Product DTO<br/>[ProductDTO.cs]"]
  node_specification["Paged specification"]
  node_repository["Repository abstraction"]
  node_response["Response wrappers<br/>[Response.cs]"]
  node_pagedresponse["Paged response<br/>[PagedResponse.cs]"]
  node_validators["Command validators"]
end

subgraph group_persistence["Persistence"]
  node_repositoryimpl["Async repository"]
  node_context["EF Core context"]
  node_database[("AdventureWorks database")]
end

subgraph group_domain["AdventureWorks domain"]
  node_product["Product entity<br/>[Product.cs]"]
  node_domainmodels["AdventureWorks entities"]
end

node_client(("API client"))

node_client -->|"sends requests"| node_controller
node_controller -->|"uses mediator"| node_base
node_controller -->|"dispatches commands"| node_commands
node_controller -->|"dispatches query"| node_getbyid
node_controller -->|"dispatches query"| node_getall
node_commands -->|"uses repository"| node_repository
node_commands -->|"manages entity"| node_product
node_commands -->|"returns wrapper"| node_response
node_getbyid -->|"loads product"| node_repository
node_getbyid -->|"maps result"| node_mapping
node_getbyid -->|"returns wrapper"| node_response
node_getall -->|"lists products"| node_repository
node_getall -->|"applies paging"| node_specification
node_getall -->|"maps results"| node_mapping
node_getall -->|"returns page"| node_pagedresponse
node_mapping -->|"maps to DTO"| node_dto
node_repositoryimpl -->|"implements interface"| node_repository
node_repositoryimpl -->|"uses context"| node_context
node_context -->|"maps entities"| node_domainmodels
node_context -.->|"reads and writes"| node_database
node_appregistration -->|"registers behavior"| node_validation
node_validators -.->|"validated by pipeline"| node_validation
node_errors -->|"builds error response"| node_response

click node_controller "https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Controllers/v1/ProductController.cs"
click node_base "https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Controllers/BaseApiController.cs"
click node_errors "https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Middleware/ErrorHandlerMiddleware.cs"
click node_commands "https://github.com/gmrodriguez12/webapi-onion/tree/master/Application/Features/Products/Commands"
click node_getbyid "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs"
click node_getall "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs"
click node_validation "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Beheaviors/ValidationBehavior.cs"
click node_appregistration "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/ServiceExtensions.cs"
click node_mapping "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Mappings/GeneralProfile.cs"
click node_dto "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/DTOs/ProductDTO.cs"
click node_specification "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Specifications/PagedProductSpecification.cs"
click node_repository "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Interfaces/IRepositoryAsync.cs"
click node_response "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Wrappers/Response.cs"
click node_pagedresponse "https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Wrappers/PagedResponse.cs"
click node_repositoryimpl "https://github.com/gmrodriguez12/webapi-onion/blob/master/Persistence/Repository/AdventureRepositoryAsync.cs"
click node_context "https://github.com/gmrodriguez12/webapi-onion/blob/master/Persistence/Data/AdventureWorkDbContext.cs"
click node_product "https://github.com/gmrodriguez12/webapi-onion/blob/master/Domain/Entities/Product.cs"
click node_domainmodels "https://github.com/gmrodriguez12/webapi-onion/tree/master/Domain/Entities"
click node_validators "https://github.com/gmrodriguez12/webapi-onion/tree/master/Application/Features/Products/Commands"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_controller,node_base,node_errors,node_client toneBlue
class node_commands,node_getbyid,node_getall,node_validation,node_appregistration,node_mapping,node_dto,node_specification,node_repository,node_response,node_pagedresponse,node_validators toneAmber
class node_repositoryimpl,node_context,node_database toneMint
class node_product,node_domainmodels toneRose
```

## Components

### HTTP API

- [Product controller](https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Controllers/v1/ProductController.cs): `WebAPI/Controllers/v1/ProductController.cs`
- [MediatR access](https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Controllers/BaseApiController.cs): `WebAPI/Controllers/BaseApiController.cs`
- [Error middleware](https://github.com/gmrodriguez12/webapi-onion/blob/master/WebAPI/Middleware/ErrorHandlerMiddleware.cs): `WebAPI/Middleware/ErrorHandlerMiddleware.cs`

### Application workflow

- [Product commands](https://github.com/gmrodriguez12/webapi-onion/tree/master/Application/Features/Products/Commands): `Application/Features/Products/Commands`
- [Get product](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs): `Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs`
- [List products](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs): `Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`
- [Validation behavior](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Beheaviors/ValidationBehavior.cs): `Application/Beheaviors/ValidationBehavior.cs`
- [Application registration](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/ServiceExtensions.cs): `Application/ServiceExtensions.cs`
- [Product mapping](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Mappings/GeneralProfile.cs): `Application/Mappings/GeneralProfile.cs`
- [Product DTO](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/DTOs/ProductDTO.cs): `Application/DTOs/ProductDTO.cs`
- [Paged specification](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Specifications/PagedProductSpecification.cs): `Application/Specifications/PagedProductSpecification.cs`
- [Repository abstraction](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Interfaces/IRepositoryAsync.cs): `Application/Interfaces/IRepositoryAsync.cs`
- [Response wrappers](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Wrappers/Response.cs): `Application/Wrappers/Response.cs`
- [Paged response](https://github.com/gmrodriguez12/webapi-onion/blob/master/Application/Wrappers/PagedResponse.cs): `Application/Wrappers/PagedResponse.cs`
- [Command validators](https://github.com/gmrodriguez12/webapi-onion/tree/master/Application/Features/Products/Commands): `Application/Features/Products/Commands`

### Persistence

- [Async repository](https://github.com/gmrodriguez12/webapi-onion/blob/master/Persistence/Repository/AdventureRepositoryAsync.cs): `Persistence/Repository/AdventureRepositoryAsync.cs`
- [EF Core context](https://github.com/gmrodriguez12/webapi-onion/blob/master/Persistence/Data/AdventureWorkDbContext.cs): `Persistence/Data/AdventureWorkDbContext.cs`
- **AdventureWorks database**

### AdventureWorks domain

- [Product entity](https://github.com/gmrodriguez12/webapi-onion/blob/master/Domain/Entities/Product.cs): `Domain/Entities/Product.cs`
- [AdventureWorks entities](https://github.com/gmrodriguez12/webapi-onion/tree/master/Domain/Entities): `Domain/Entities`

### Other components

- **API client**

## Connections

- API client → Product controller: sends requests (evidence: `WebAPI/Controllers/v1/ProductController.cs`)
- Product controller → MediatR access: uses mediator (evidence: `WebAPI/Controllers/v1/ProductController.cs`)
- Product controller → Product commands: dispatches commands (evidence: `WebAPI/Controllers/v1/ProductController.cs`)
- Product controller → Get product: dispatches query (evidence: `WebAPI/Controllers/v1/ProductController.cs`)
- Product controller → List products: dispatches query (evidence: `WebAPI/Controllers/v1/ProductController.cs`)
- Product commands → Repository abstraction: uses repository (evidence: `Application/Features/Products/Commands/CreateProductCommand/CreateProductCommand.cs`)
- Product commands → Product entity: manages entity (evidence: `Application/Features/Products/Commands/CreateProductCommand/CreateProductCommand.cs`)
- Product commands → Response wrappers: returns wrapper (evidence: `Application/Features/Products/Commands/CreateProductCommand/CreateProductCommand.cs`)
- Get product → Repository abstraction: loads product (evidence: `Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs`)
- Get product → Product mapping: maps result (evidence: `Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs`)
- Get product → Response wrappers: returns wrapper (evidence: `Application/Features/Products/Queries/GetProductByIdQuery/GetProductByIdQuery.cs`)
- List products → Repository abstraction: lists products (evidence: `Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`)
- List products → Paged specification: applies paging (evidence: `Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`)
- List products → Product mapping: maps results (evidence: `Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`)
- List products → Paged response: returns page (evidence: `Application/Features/Products/Queries/GetAllProductsQuery/GetAllProductsQuery.cs`)
- Product mapping → Product DTO: maps to DTO (evidence: `Application/Mappings/GeneralProfile.cs`)
- Async repository → Repository abstraction: implements interface (evidence: `Persistence/Repository/AdventureRepositoryAsync.cs`)
- Async repository → EF Core context: uses context (evidence: `Persistence/Repository/AdventureRepositoryAsync.cs`)
- EF Core context → AdventureWorks entities: maps entities (evidence: `Persistence/Data/AdventureWorkDbContext.cs`)
- EF Core context → AdventureWorks database: reads and writes
- Application registration → Validation behavior: registers behavior (evidence: `Application/ServiceExtensions.cs`)
- Command validators → Validation behavior: validated by pipeline
- Error middleware → Response wrappers: builds error response (evidence: `WebAPI/Middleware/ErrorHandlerMiddleware.cs`)
