Skip to content

Mahmoud23199/bolt

Repository files navigation

Clean Architecture .NET 8 Web API Template

A production-ready, enterprise-grade .NET 8 Web API template following Clean Architecture principles and industry best practices. This template is designed to be reusable as a foundation for multiple projects and can easily integrate with modern frontend frameworks.

Architecture Overview

This template implements Clean Architecture with clear separation of concerns across four distinct layers:

src/
├── CleanArchitecture.API/              # Presentation Layer
│   ├── Controllers/                    # API Controllers
│   ├── Middleware/                     # Custom middleware
│   └── Program.cs                      # Application entry point
│
├── CleanArchitecture.Application/      # Business Logic Layer
│   ├── Common/                         # Shared application logic
│   │   ├── Behaviours/                 # MediatR pipeline behaviours
│   │   ├── Interfaces/                 # Application interfaces
│   │   └── Models/                     # DTOs and response models
│   └── Features/                       # Feature-based organization
│       └── Products/                   # Example: Product feature
│           ├── Commands/               # CQRS Commands
│           ├── Queries/                # CQRS Queries
│           └── DTOs/                   # Data Transfer Objects
│
├── CleanArchitecture.Domain/           # Domain Layer
│   ├── Common/                         # Base entities and interfaces
│   └── Entities/                       # Domain entities
│
└── CleanArchitecture.Infrastructure/   # Infrastructure Layer
    ├── Persistence/                    # Database context and repositories
    └── Services/                       # External services implementation

Features

Core Architecture

  • Clean Architecture with strict layer separation
  • CQRS Pattern using MediatR
  • Repository Pattern for data access
  • Unit of Work for transaction management
  • Dependency Injection throughout
  • SOLID Principles applied consistently

API Features

  • Global Exception Handling - Custom middleware with structured error responses
  • Request Logging - Comprehensive request/response logging with Serilog
  • JWT Authentication - Token-based authentication with role support
  • Role-Based Authorization - Fine-grained access control
  • API Response Wrapper - Consistent response format across all endpoints
  • Pagination, Filtering & Sorting - Generic implementation for all list endpoints
  • FluentValidation - Automatic request validation
  • AutoMapper - Object-to-object mapping
  • Swagger/OpenAPI - Interactive API documentation with JWT support
  • Rate Limiting - Built-in request throttling
  • Health Checks - Database and application health monitoring
  • CORS - Configurable cross-origin resource sharing
  • In-Memory Caching - Ready to extend to Redis

Database

  • Entity Framework Core 8 with PostgreSQL
  • Supabase Integration - Ready for cloud deployment
  • Generic Repository Pattern - Reusable data access
  • Soft Delete Support - Entities marked as deleted instead of removed
  • Audit Fields - CreatedAt, UpdatedAt, CreatedBy, UpdatedBy

Developer Experience

  • Feature-Based Organization - Easy to navigate and extend
  • Example CRUD Module - Complete Products example
  • Strongly Typed Configuration - Type-safe settings
  • Environment-Based Configs - Development and production settings

Getting Started

Prerequisites

  • .NET 8 SDK
  • PostgreSQL (or Supabase account)
  • IDE (Visual Studio 2022, VS Code, or Rider)

Installation

  1. Clone the repository

    git clone <repository-url>
    cd CleanArchitecture
  2. Configure environment variables

    Copy .env.example to .env and update with your values:

    cp .env.example .env

    Required variables:

    SUPABASE_URL=your_supabase_url
    SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
    JWT_SECRET=your_jwt_secret_key
    
  3. Restore dependencies

    dotnet restore
  4. Update database

    cd src/CleanArchitecture.API
    dotnet ef database update
  5. Run the application

    dotnet run

The API will be available at https://localhost:5001 and Swagger UI at https://localhost:5001

Database Migrations

Creating a new migration

cd src/CleanArchitecture.API
dotnet ef migrations add MigrationName --project ../CleanArchitecture.Infrastructure

Applying migrations

dotnet ef database update

Removing last migration

dotnet ef migrations remove --project ../CleanArchitecture.Infrastructure

API Documentation

Once running, access the Swagger UI at the root URL to explore and test all endpoints.

Authentication

  1. Login to get JWT token

    POST /api/auth/login
    {
      "username": "admin",
      "password": "admin123"
    }
    

    Default users:

    • Admin: admin / admin123
    • User: user / user123
  2. Use the token in Swagger

    • Click "Authorize" button
    • Enter: Bearer {your-token}
    • Click "Authorize"

Example Endpoints

Products

  • GET /api/products - Get paginated products
  • GET /api/products/{id} - Get product by ID
  • POST /api/products - Create product (Admin only)
  • PUT /api/products/{id} - Update product (Admin only)
  • DELETE /api/products/{id} - Delete product (Admin only)

Query parameters for listing:

  • pageNumber - Page number (default: 1)
  • pageSize - Items per page (default: 10, max: 100)
  • sortBy - Sort field (name, price, createdAt)
  • sortDescending - Sort direction (default: false)
  • searchTerm - Search in name and description
  • category - Filter by category
  • isActive - Filter by active status

Adding New Features

1. Create Domain Entity

// src/CleanArchitecture.Domain/Entities/YourEntity.cs
public class YourEntity : BaseEntity
{
    public string Name { get; set; } = string.Empty;
    // Add your properties
}

2. Update DbContext

// src/CleanArchitecture.Infrastructure/Persistence/ApplicationDbContext.cs
public DbSet<YourEntity> YourEntities => Set<YourEntity>();

3. Create DTOs

// src/CleanArchitecture.Application/Features/YourFeature/DTOs/YourEntityDto.cs
public class YourEntityDto
{
    public Guid Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

4. Create Commands and Queries

// src/CleanArchitecture.Application/Features/YourFeature/Commands/CreateYourEntity/CreateYourEntityCommand.cs
public class CreateYourEntityCommand : IRequest<YourEntityDto>
{
    public string Name { get; set; } = string.Empty;
}

5. Create Command/Query Handlers

// src/CleanArchitecture.Application/Features/YourFeature/Commands/CreateYourEntity/CreateYourEntityCommandHandler.cs
public class CreateYourEntityCommandHandler : IRequestHandler<CreateYourEntityCommand, YourEntityDto>
{
    // Implement handler logic
}

6. Add Validators

// src/CleanArchitecture.Application/Features/YourFeature/Commands/CreateYourEntity/CreateYourEntityCommandValidator.cs
public class CreateYourEntityCommandValidator : AbstractValidator<CreateYourEntityCommand>
{
    public CreateYourEntityCommandValidator()
    {
        RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
    }
}

7. Create Controller

// src/CleanArchitecture.API/Controllers/YourEntitiesController.cs
[ApiController]
[Route("api/[controller]")]
public class YourEntitiesController : ControllerBase
{
    private readonly IMediator _mediator;

    public YourEntitiesController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpPost]
    public async Task<ActionResult<ApiResponse<YourEntityDto>>> Create([FromBody] CreateYourEntityCommand command)
    {
        var result = await _mediator.Send(command);
        return Ok(ApiResponse<YourEntityDto>.SuccessResponse(result));
    }
}

8. Add Mapping Profile

// src/CleanArchitecture.Application/Features/YourFeature/MappingProfile.cs
public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<YourEntity, YourEntityDto>();
    }
}

9. Create and Apply Migration

dotnet ef migrations add AddYourEntity --project src/CleanArchitecture.Infrastructure
dotnet ef database update

Configuration

appsettings.json

Configure application settings in src/CleanArchitecture.API/appsettings.json:

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information"
    }
  },
  "AllowedHosts": "*"
}

Environment Variables

The following environment variables are supported:

  • SUPABASE_URL - Supabase project URL
  • SUPABASE_SERVICE_ROLE_KEY - Supabase service role key
  • JWT_SECRET - Secret key for JWT token generation
  • JWT_ISSUER - JWT token issuer
  • JWT_AUDIENCE - JWT token audience
  • JWT_EXPIRATION_MINUTES - Token expiration time in minutes
  • ASPNETCORE_ENVIRONMENT - Environment (Development/Production)

Frontend Integration

This API is designed to work seamlessly with modern frontend frameworks:

React/Next.js Example

const API_URL = 'https://your-api-url.com';

// Login
const login = async (username: string, password: string) => {
  const response = await fetch(`${API_URL}/api/auth/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username, password })
  });
  const data = await response.json();
  return data.data.token;
};

// Get products with pagination
const getProducts = async (page: number, pageSize: number) => {
  const response = await fetch(
    `${API_URL}/api/products?pageNumber=${page}&pageSize=${pageSize}`,
    {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    }
  );
  const data = await response.json();
  return data.data;
};

Angular Example

import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable()
export class ApiService {
  private apiUrl = 'https://your-api-url.com';

  constructor(private http: HttpClient) {}

  login(username: string, password: string) {
    return this.http.post(`${this.apiUrl}/api/auth/login`,
      { username, password });
  }

  getProducts(page: number, pageSize: number) {
    const headers = new HttpHeaders({
      'Authorization': `Bearer ${this.token}`
    });
    return this.http.get(`${this.apiUrl}/api/products`, {
      headers,
      params: { pageNumber: page, pageSize }
    });
  }
}

Security Best Practices

This template implements several security measures:

  • JWT Authentication - Secure token-based authentication
  • Role-Based Authorization - Granular access control
  • Input Validation - FluentValidation on all inputs
  • SQL Injection Prevention - Parameterized queries via EF Core
  • CORS Configuration - Controlled cross-origin access
  • Rate Limiting - Protection against abuse
  • Secure Password Handling - Never log or expose credentials
  • HTTPS Redirection - Force secure connections

Production Checklist

Before deploying to production:

  • Change default JWT secret
  • Update authentication to use real user database
  • Configure CORS for specific origins only
  • Set appropriate rate limits
  • Enable HTTPS
  • Configure logging to external service
  • Set up health check monitoring
  • Review and adjust cache expiration times
  • Disable Swagger in production (or protect it)
  • Set up proper database backups

Testing

Manual Testing with Swagger

  1. Run the application
  2. Navigate to the root URL
  3. Use the interactive Swagger UI to test endpoints

Testing with Postman/Thunder Client

Import the OpenAPI spec from /swagger/v1/swagger.json

Project Structure Best Practices

Layer Dependencies

  • API → Application, Infrastructure
  • Application → Domain
  • Infrastructure → Application, Domain
  • Domain → None (no dependencies)

Naming Conventions

  • Commands: {Verb}{Entity}Command (e.g., CreateProductCommand)
  • Queries: Get{Entity}Query (e.g., GetProductByIdQuery)
  • DTOs: {Entity}Dto (e.g., ProductDto)
  • Validators: {Command/Query}Validator
  • Handlers: {Command/Query}Handler

Performance Tips

  1. Use Caching - Cache frequently accessed data
  2. Optimize Queries - Use pagination for large datasets
  3. Async/Await - All database operations are async
  4. Connection Pooling - EF Core handles this automatically
  5. Index Database - Add indexes for frequently queried columns

Troubleshooting

Database Connection Issues

  • Verify Supabase credentials in .env
  • Check network connectivity
  • Ensure database is accessible

Migration Errors

  • Delete existing migrations and recreate
  • Verify connection string
  • Check entity configurations

Authentication Issues

  • Verify JWT secret is configured
  • Check token expiration time
  • Ensure proper Bearer token format

Contributing

When contributing to this template:

  1. Follow existing code style and patterns
  2. Add tests for new features
  3. Update documentation
  4. Create feature branches
  5. Submit pull requests with clear descriptions

License

This template is provided as-is for use in your projects.

Support

For issues and questions:

  • Check existing documentation
  • Review example implementations
  • Consult the Clean Architecture principles

Roadmap

Future enhancements:

  • Unit and integration tests
  • Docker support
  • CI/CD pipeline examples
  • Message queue integration
  • Redis caching
  • Email service
  • File upload/storage
  • Audit logging
  • API versioning
  • GraphQL endpoint option

Built with ❤️ using .NET 8 and Clean Architecture principles

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors