Level Four

Level Four

Internship Preparation - CLEAN API Architecture

Select a week

Clean API Architecture with EF Core

Building scalable APIs using Clean Architecture principles, layered design, and Entity Framework Core

Week 1

Topics

Clean Architecture Principles

Understanding layered architecture and separation of concerns

Key Points

  • Separate business logic from infrastructure concerns
  • Dependencies point inward toward the domain
  • Core layers have no external dependencies
  • Use interfaces to define contracts between layers
  • Testable, maintainable, and scalable code structure

Interactive Code Examples

// Clean Architecture has 5 main layers:

// 1. Domain Layer (Core/Entities)
//    - Business entities and domain logic
//    - No dependencies on other layers
//    - Pure C# classes

namespace MyApp.Domain.Entities
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public decimal Price { get; set; }
        public string Category { get; set; } = string.Empty;
        public DateTime CreatedAt { get; set; }
        public DateTime? UpdatedAt { get; set; }
        
        // Domain logic
        public void UpdatePrice(decimal newPrice)
        {
            if (newPrice <= 0)
                throw new ArgumentException("Price must be greater than zero");
                
            Price = newPrice;
            UpdatedAt = DateTime.UtcNow;
        }
    }
}

// 2. Application Layer (Use Cases/Business Logic)
//    - Application-specific business rules
//    - Defines interfaces for infrastructure and persistence
//    - Orchestrates domain objects

namespace MyApp.Application.Interfaces
{
    public interface IProductRepository
    {
        Task<Product?> GetByIdAsync(int id);
        Task<IEnumerable<Product>> GetAllAsync();
        Task<Product> AddAsync(Product product);
        Task UpdateAsync(Product product);
        Task DeleteAsync(int id);
    }
}

// 3. Infrastructure Layer
//    - External concerns (email, file storage, third-party APIs)
//    - Implements non-database interfaces from Application layer
//    - Does NOT contain the database — that belongs in Persistence

namespace MyApp.Infrastructure.Services
{
    public class EmailService : IEmailService
    {
        public async Task SendOrderConfirmationAsync(string to, int orderId)
        {
            // SendGrid, SMTP, or any email provider
        }
    }
}

// 4. Persistence Layer
//    - Database only: EF Core DbContext, repositories, migrations
//    - Implements repository interfaces defined in Application layer
//    - Keeps EF Core completely out of Domain and Application

namespace MyApp.Persistence.Context
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options) { }

        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfigurationsFromAssembly(
                typeof(ApplicationDbContext).Assembly);
        }
    }
}

// 5. Presentation Layer (API/Controllers)
//    - User interface / API endpoints
//    - Depends on Application layer only
//    - Handles HTTP requests/responses

namespace MyApp.API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly IProductRepository _repository;

        public ProductsController(IProductRepository repository)
        {
            _repository = repository;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
        {
            var products = await _repository.GetAllAsync();
            return Ok(products);
        }
    }
}

💡 Explanation: Clean Architecture separates concerns into 5 layers. Domain has no dependencies. Application defines interfaces and use cases. Infrastructure handles external services (email, storage). Persistence handles database access (EF Core, repositories, migrations). Presentation (API) handles HTTP. Dependencies flow inward toward Domain.

Architecture Patterns

Clean Architecture

Layered with dependency inversion

When to use:

Large applications, long-term maintenance

Example:

Enterprise APIs, complex business logic

N-Tier Architecture

Traditional layered approach

When to use:

Medium-sized applications

Example:

Standard CRUD applications

Monolithic

All code in one project

When to use:

Small applications, prototypes

Example:

Simple APIs, learning projects