Skip to main content

Introduction

The Catalog service is a microservice responsible for managing the product catalog in the AspNetRun e-commerce system. It provides a complete CRUD API for products, allowing you to create, read, update, and delete product information.

Architecture

Vertical Slice Architecture

The Catalog service implements Vertical Slice Architecture, where each feature is organized in its own folder with all related components:
Catalog.API/
├── Products/
│   ├── CreateProduct/
│   │   ├── CreateProductHandler.cs
│   │   └── CreateProductEndpoint.cs
│   ├── GetProducts/
│   │   ├── GetProductsHandler.cs
│   │   └── GetProductsEndpoint.cs
│   ├── GetProductById/
│   │   ├── GetProductByIdHandler.cs
│   │   └── GetProductByIdEndpoint.cs
│   ├── GetProductByCategory/
│   │   ├── GetProductByCategoryHandler.cs
│   │   └── GetProductByCategoryEndpoint.cs
│   ├── UpdateProduct/
│   │   ├── UpdateProductHandler.cs
│   │   └── UpdateProductEndpoint.cs
│   └── DeleteProduct/
│       ├── DeleteProductHandler.cs
│       └── DeleteProductEndpoint.cs
├── Models/
│   └── Product.cs
├── Data/
│   └── CatalogInitialData.cs
└── Program.cs
Each feature slice contains:
  • Endpoint: Defines the HTTP route using Carter
  • Handler: Implements business logic using MediatR
  • Request/Response: DTOs for API contracts
  • Command/Query: CQRS objects for internal operations
  • Validator: FluentValidation rules

Technology Stack

Carter

Minimal API routing framework for defining endpoints

MediatR

CQRS implementation with Command/Query handlers

Marten

Document database using PostgreSQL as the backing store

FluentValidation

Declarative validation rules for commands and queries

Key Components

Product Model

The core domain entity representing a product:
public class Product
{
    public Guid Id { get; set; }
    public string Name { get; set; } = default!;
    public List<string> Category { get; set; } = new();
    public string Description { get; set; } = default!;
    public string ImageFile { get; set; } = default!;
    public decimal Price { get; set; }
}

CQRS Pattern

The service separates read and write operations: Commands (Write operations):
  • CreateProductCommand - Create new products
  • UpdateProductCommand - Update existing products
  • DeleteProductCommand - Delete products
Queries (Read operations):
  • GetProductsQuery - Get paginated product list
  • GetProductByIdQuery - Get single product by ID
  • GetProductByCategoryQuery - Get products by category

Middleware Pipeline

The service uses MediatR behaviors for cross-cutting concerns:
builder.Services.AddMediatR(config =>
{
    config.RegisterServicesFromAssembly(assembly);
    config.AddOpenBehavior(typeof(ValidationBehavior<,>));
    config.AddOpenBehavior(typeof(LoggingBehavior<,>));
});
  • ValidationBehavior: Automatic request validation using FluentValidation
  • LoggingBehavior: Request/response logging for observability

API Endpoints

The Catalog service exposes the following REST endpoints:
MethodEndpointDescription
GET/productsGet paginated list of products
GET/products/{id}Get product by ID
GET/products/category/{category}Get products by category
POST/productsCreate new product
PUT/productsUpdate existing product
DELETE/products/{id}Delete product
GET/healthHealth check endpoint

Exception Handling

The service implements global exception handling:
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
app.UseExceptionHandler(options => { });
Custom exceptions:
  • ProductNotFoundException - Thrown when a product is not found by ID

Health Checks

Health monitoring with PostgreSQL database check:
builder.Services.AddHealthChecks()
    .AddNpgSql(builder.Configuration.GetConnectionString("Database")!);

app.UseHealthChecks("/health",
    new HealthCheckOptions
    {
        ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
    });

Getting Started

Prerequisites

  • .NET 8.0 SDK
  • PostgreSQL database
  • Docker (optional, for containerized deployment)

Configuration

Configure the database connection in appsettings.json:
{
  "ConnectionStrings": {
    "Database": "Host=localhost;Database=CatalogDb;Username=postgres;Password=postgres"
  }
}

Running the Service

cd src/Services/Catalog/Catalog.API
dotnet run
The service will start on http://localhost:5001 (or as configured).

Next Steps

Features

Explore all product management features

API Reference

View detailed API documentation

Database

Learn about Marten and data persistence

Architecture

Deep dive into Vertical Slice Architecture

Build docs developers (and LLMs) love