Complete REST API Capstone Project โ€” Product Management CRUD Masterclass

โšก C# 12 & .NET 8 ๐ŸŸข Chapter 35 of 35 ๐Ÿ“‚ Phase 12: ASP.NET Core Web APIs ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: Product Model ยท DTO Design ยท IProductService Interface ยท Dependency Injection ยท Full CRUD Controller ยท HTTP Status Codes ยท Swagger Testing ยท API Documentation

Welcome to Phase 12 (Chapter 35): Complete ASP.NET Core REST API Capstone Project โ€” Product Management CRUD System! This is the final capstone lesson that ties together everything learned in this masterclass. We build a complete, production-ready Product Management REST API using ASP.NET Core 8 with: Product model, ProductDto, IProductService interface, ProductService implementation, ProductsController with full CRUD, in-memory repository, data validation, proper HTTP status codes, and Swagger documentation.

1Project Architecture
REST API Project Structure: ProductsAPI/ โ”œโ”€โ”€ Program.cs โ† App host setup, DI registration, middleware pipeline โ”œโ”€โ”€ Models/ โ”‚ โ””โ”€โ”€ Product.cs โ† Domain Entity (Id, Name, Price, Stock, Category) โ”œโ”€โ”€ DTOs/ โ”‚ โ”œโ”€โ”€ CreateProductDto.cs โ† Input DTO for POST requests (with validation) โ”‚ โ””โ”€โ”€ UpdateProductDto.cs โ† Input DTO for PUT requests โ”œโ”€โ”€ Services/ โ”‚ โ”œโ”€โ”€ IProductService.cs โ† Interface contract (Dependency Inversion) โ”‚ โ””โ”€โ”€ ProductService.cs โ† In-memory service implementation โ””โ”€โ”€ Controllers/ โ””โ”€โ”€ ProductsController.cs โ† API Controller with CRUD actions
2Complete Product Model & DTOs
C# โ€” Product Entity & DTOs โ–ถ Run in Compiler
// Models/Product.cs
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
    public int Stock { get; set; }
    public string Category { get; set; } = "";
}

// DTOs/CreateProductDto.cs
public class CreateProductDto
{
    [Required, MinLength(2), MaxLength(100)]
    public string Name { get; set; } = "";

    [Required, Range(0.01, 10000000)]
    public decimal Price { get; set; }

    [Required, Range(0, int.MaxValue)]
    public int Stock { get; set; }

    [Required]
    public string Category { get; set; } = "";
}
3Service Interface & In-Memory Implementation
C# โ€” IProductService & ProductService โ–ถ Run in Compiler
// Services/IProductService.cs
public interface IProductService
{
    List<Product> GetAll();
    Product? GetById(int id);
    Product Create(CreateProductDto dto);
    Product? Update(int id, CreateProductDto dto);
    bool Delete(int id);
}

// Services/ProductService.cs
public class ProductService : IProductService
{
    private readonly List<Product> _products = new()
    {
        new Product { Id = 1, Name = "Laptop",   Price = 75000, Stock = 10, Category = "Electronics" },
        new Product { Id = 2, Name = "Mouse",    Price = 1200,  Stock = 50, Category = "Accessories" },
        new Product { Id = 3, Name = "Keyboard", Price = 2500,  Stock = 30, Category = "Accessories" }
    };

    private int _nextId = 4;

    public List<Product> GetAll() => _products;

    public Product? GetById(int id) => _products.FirstOrDefault(p => p.Id == id);

    public Product Create(CreateProductDto dto)
    {
        var product = new Product { Id = _nextId++, Name = dto.Name, Price = dto.Price, Stock = dto.Stock, Category = dto.Category };
        _products.Add(product);
        return product;
    }

    public Product? Update(int id, CreateProductDto dto)
    {
        var product = GetById(id);
        if (product is null) return null;
        product.Name = dto.Name;
        product.Price = dto.Price;
        product.Stock = dto.Stock;
        product.Category = dto.Category;
        return product;
    }

    public bool Delete(int id)
    {
        var product = GetById(id);
        if (product is null) return false;
        _products.Remove(product);
        return true;
    }
}
4Complete ProductsController with All CRUD Endpoints
C# โ€” ProductsController Full CRUD โ–ถ Run in Compiler
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _service;

    public ProductsController(IProductService service) // DI via constructor injection
    {
        _service = service;
    }

    // GET /api/products โ€” Get ALL products
    [HttpGet]
    public ActionResult<List<Product>> GetAll() => Ok(_service.GetAll());

    // GET /api/products/1 โ€” Get ONE product
    [HttpGet("{id:int}")]
    public ActionResult<Product> GetById(int id)
    {
        var product = _service.GetById(id);
        return product is null ? NotFound(new { Message = $"Product {id} not found." }) : Ok(product);
    }

    // POST /api/products โ€” CREATE product
    [HttpPost]
    public ActionResult<Product> Create([FromBody] CreateProductDto dto)
    {
        var product = _service.Create(dto);
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }

    // PUT /api/products/1 โ€” UPDATE product
    [HttpPut("{id:int}")]
    public ActionResult<Product> Update(int id, [FromBody] CreateProductDto dto)
    {
        var product = _service.Update(id, dto);
        return product is null ? NotFound(new { Message = $"Product {id} not found." }) : Ok(product);
    }

    // DELETE /api/products/1 โ€” DELETE product
    [HttpDelete("{id:int}")]
    public IActionResult Delete(int id)
    {
        bool deleted = _service.Delete(id);
        return deleted ? NoContent() : NotFound(new { Message = $"Product {id} not found." });
    }
}

// Program.cs โ€” Register ProductService and run app
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IProductService, ProductService>(); // Register DI

var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapControllers();
app.Run();
5Technical FAQs

Q1: What HTTP status codes should CRUD operations return?

GET โ†’ 200 OK (found) / 404 Not Found; POST โ†’ 201 Created; PUT โ†’ 200 OK / 404 Not Found; DELETE โ†’ 204 No Content / 404 Not Found; Validation error โ†’ 400 Bad Request.

Q2: What is the next step after this masterclass?

Learn Entity Framework Core for database persistence, JWT Authentication for security, Fluent Validation, and deploy your API to Azure App Service or Docker containers.