Skip to content

Latest commit

 

History

History
302 lines (243 loc) · 8.13 KB

File metadata and controls

302 lines (243 loc) · 8.13 KB

Quick Start Guide - Product API

🚀 Running the Application

# Navigate to project root
cd C:\Users\me\RiderProjects\DotNetCleanArchitecture

# Restore and build
dotnet restore
dotnet build

# Run the API
cd src\DotNetCleanArchitecture.WebAPI
dotnet run

The API will start at: https://localhost:5001


📍 API Endpoints

Method Endpoint Description
GET /api/products Get all products
GET /api/products/{id} Get product by ID
POST /api/products Create new product
PUT /api/products/{id} Update product
DELETE /api/products/{id} Delete product

🧪 Test the API (PowerShell)

Create a Product

$body = @{
    name = "Wireless Mouse"
    description = "Ergonomic wireless mouse"
    sku = "MOUSE-001"
    price = 29.99
    currency = "USD"
    stockQuantity = 50
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://localhost:5001/api/products" `
    -Method POST `
    -Body $body `
    -ContentType "application/json" `
    -SkipCertificateCheck

Get All Products

Invoke-RestMethod -Uri "https://localhost:5001/api/products" `
    -Method GET `
    -SkipCertificateCheck

Get Product by ID

$productId = "YOUR-PRODUCT-ID-HERE"
Invoke-RestMethod -Uri "https://localhost:5001/api/products/$productId" `
    -Method GET `
    -SkipCertificateCheck

Update Product

$productId = "YOUR-PRODUCT-ID-HERE"
$body = @{
    name = "Wireless Mouse Pro"
    description = "Updated description"
    price = 34.99
    currency = "USD"
} | ConvertTo-Json

Invoke-RestMethod -Uri "https://localhost:5001/api/products/$productId" `
    -Method PUT `
    -Body $body `
    -ContentType "application/json" `
    -SkipCertificateCheck

Delete Product

$productId = "YOUR-PRODUCT-ID-HERE"
Invoke-RestMethod -Uri "https://localhost:5001/api/products/$productId" `
    -Method DELETE `
    -SkipCertificateCheck

📂 Project Structure

src/
├── Domain/                    [No dependencies - Pure business logic]
│   ├── Common/               [Base classes]
│   │   ├── BaseEntity.cs
│   │   ├── IDomainEvent.cs
│   │   └── ValueObject.cs
│   ├── Entities/             [Aggregate roots]
│   │   └── Product.cs
│   ├── ValueObjects/         [Immutable values]
│   │   └── Money.cs
│   └── DomainEvents/         [Domain events]
│       ├── ProductCreatedDomainEvent.cs
│       ├── ProductUpdatedDomainEvent.cs
│       └── ProductStockChangedDomainEvent.cs
│
├── Application/              [Use cases & business orchestration]
│   ├── DTOs/                 [Data transfer objects]
│   │   ├── ProductDto.cs
│   │   ├── CreateProductDto.cs
│   │   └── UpdateProductDto.cs
│   ├── Interfaces/           [Repository contracts]
│   │   ├── IProductRepository.cs
│   │   └── IUnitOfWork.cs
│   ├── UseCases/
│   │   └── Products/
│   │       ├── Commands/     [Write operations - CQRS]
│   │       │   ├── CreateProductCommand.cs
│   │       │   ├── UpdateProductCommand.cs
│   │       │   └── DeleteProductCommand.cs
│   │       └── Queries/      [Read operations - CQRS]
│   │           ├── GetAllProductsQuery.cs
│   │           └── GetProductByIdQuery.cs
│   └── DependencyInjection.cs
│
├── Infrastructure/           [External concerns implementation]
│   ├── Persistence/
│   │   ├── ApplicationDbContext.cs
│   │   ├── UnitOfWork.cs
│   │   ├── Configurations/
│   │   │   └── ProductConfiguration.cs
│   │   └── Repositories/
│   │       └── ProductRepository.cs
│   └── DependencyInjection.cs
│
└── WebAPI/                   [HTTP API layer]
    ├── Controllers/
    │   └── ProductsController.cs
    ├── Program.cs
    └── Products.http         [Test file]

🎯 Key Concepts Demonstrated

1. Clean Architecture Layers

  • Domain: Business rules and entities (no dependencies)
  • Application: Use cases and orchestration (depends on Domain)
  • Infrastructure: Data access and external services (depends on Application)
  • WebAPI: HTTP endpoints and presentation (depends on Application & Infrastructure)

2. Domain-Driven Design

  • Aggregate Root: Product entity encapsulates business logic
  • Value Objects: Money represents immutable monetary values
  • Domain Events: Track important business events
  • Factory Methods: Product.Create() enforces invariants

3. CQRS Pattern

  • Commands: CreateProductCommand, UpdateProductCommand, DeleteProductCommand
  • Queries: GetAllProductsQuery, GetProductByIdQuery
  • Clear separation between read and write operations

4. Repository Pattern

  • Interface in Application layer: IProductRepository
  • Implementation in Infrastructure layer: ProductRepository
  • Abstracts data access from business logic

5. Unit of Work Pattern

  • IUnitOfWork manages transactions
  • Ensures consistency across multiple operations

🔍 Code Examples

Creating a Product (Domain Layer)

// Factory method enforces business rules
var price = Money.Create(29.99m, "USD");
var product = Product.Create(
    name: "Wireless Mouse",
    description: "Ergonomic mouse",
    sku: "MOUSE-001",
    price: price,
    stockQuantity: 50
);

// Business operations
product.AddStock(10);      // Increases stock
product.RemoveStock(5);    // Decreases stock
product.Activate();        // Activates product
product.Deactivate();      // Deactivates product

Using a Command (Application Layer)

// Inject the command in your controller
private readonly CreateProductCommand _createProductCommand;

// Execute the command
var dto = new CreateProductDto { /* ... */ };
var result = await _createProductCommand.ExecuteAsync(dto, cancellationToken);

Querying Data (Application Layer)

// Inject the query
private readonly GetAllProductsQuery _getAllProductsQuery;

// Execute the query
var products = await _getAllProductsQuery.ExecuteAsync(cancellationToken);

📊 Database

Currently using InMemory database for easy testing.

Database Tables Created

  • Products - Main product table with all fields
  • Index on Sku column (unique)

Switching to SQL Server

See PRODUCT_IMPLEMENTATION.md for detailed instructions.


✅ What's Working

✅ Solution builds successfully ✅ All layers properly separated ✅ Dependency injection configured ✅ Repository pattern implemented ✅ CQRS pattern implemented ✅ Domain events support ✅ Value objects (Money) ✅ EF Core configuration ✅ RESTful API endpoints ✅ InMemory database ready ✅ Error handling ✅ Logging integration


📚 Documentation

  • IMPLEMENTATION_SUMMARY.md - Complete overview of implementation
  • PRODUCT_IMPLEMENTATION.md - Detailed technical documentation
  • README.md - Project overview and architecture
  • QUICKSTART.md - This file (quick reference)

💡 Tips

  1. Use the HTTP file: Open Products.http in Rider/VS Code for easy testing
  2. Check logs: Console output shows detailed operation logs
  3. Domain logic: Business rules are in Product.cs - start there
  4. Add features: Extend by creating new commands/queries
  5. Testing: Each layer can be tested independently

🐛 Troubleshooting

Port already in use

# Change port in launchSettings.json or run on different port
dotnet run --urls "https://localhost:5002"

Certificate errors

# Trust the development certificate
dotnet dev-certs https --trust

Build errors

# Clean and rebuild
dotnet clean
dotnet restore
dotnet build

🎉 You're Ready!

The Product entity implementation is complete and follows all best practices. Start the application and begin testing the API!

Next: Open Products.http and start testing the endpoints! 🚀