A .NET Core Web API for managing product catalogs and processing orders. This project demonstrates clean architecture principles and handles concurrent order processing without overselling inventory.
E-commerce platforms often struggle with inventory management during high traffic periods. When multiple customers try to purchase the same product simultaneously, systems can oversell inventory, leading to customer dissatisfaction and operational issues. This API solves that problem through proper concurrency control.
- Product Management: Full CRUD operations for product catalog
- Order Processing: Place orders with automatic stock validation
- Concurrency Control: Prevents overselling during simultaneous orders
- Clean Architecture: Organized codebase following SOLID principles
- Database Flexibility: Supports both SQLite (development) and PostgreSQL (production)
- .NET 9.0 - Latest LTS framework
- ASP.NET Core - Web API framework
- Entity Framework Core - ORM for database operations
- PostgreSQL/SQLite - Database options
- AutoMapper - Object mapping
- FluentValidation - Input validation
- Serilog - Structured logging
- xUnit - Testing framework
- .NET 9.0 SDK
- Git
- Docker (optional)
-
Clone the repository:
git clone https://github.com/ObeeJ/ProductCatalogAPI.git cd ProductCatalogAPI -
Start the application:
dotnet run --project src/ProductCatalogAPI.API
-
Access the API:
- API: https://localhost:7000
- Documentation: https://localhost:7000/swagger
For a complete setup with PostgreSQL:
docker-compose up --buildThe API will be available at http://localhost:8080
GET /api/products- List products (with pagination)GET /api/products/{id}- Get specific productPOST /api/products- Create new productPUT /api/products/{id}- Update productDELETE /api/products/{id}- Delete product
POST /api/orders- Place an order
curl -X POST https://localhost:7000/api/products \
-H "Content-Type: application/json" \
-d '{
"name": "Wireless Headphones",
"description": "Noise-cancelling wireless headphones",
"price": 199.99,
"stockQuantity": 50
}'curl -X POST https://localhost:7000/api/orders \
-H "Content-Type: application/json" \
-d '{
"orderItems": [
{
"productId": "your-product-id-here",
"quantity": 2
}
]
}'The system prevents overselling through database transactions and optimistic concurrency control. When multiple orders are placed simultaneously:
- Each request starts a database transaction
- Stock levels are validated atomically
- Only orders with sufficient stock succeed
- Failed orders receive clear error messages
- Stock is never reduced below zero
The project follows Clean Architecture with four layers:
- Domain: Core business entities and rules
- Application: Business logic and use cases
- Infrastructure: Data access and external services
- API: HTTP endpoints and presentation logic
This structure ensures the code is testable, maintainable, and follows separation of concerns.
Run the test suite:
dotnet testThe project includes:
- Unit tests for business logic
- Integration tests for API endpoints
- Concurrency tests to verify stock management
By default, the application uses SQLite for development. To use PostgreSQL:
{
"UsePostgreSQL": true,
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=ProductCatalog;Username=postgres;Password=yourpassword"
}
}Optimistic concurrency was chosen over pessimistic locking because:
- Better performance under normal load
- Avoids deadlock scenarios
- Scales better with multiple users
- Provides clear error messages when conflicts occur
- SQLite for development: No setup required, easy testing
- PostgreSQL for production: Robust, scalable, handles concurrency well
Clean Architecture provides:
- Clear separation of concerns
- Easy unit testing
- Framework independence
- Maintainable codebase
This project is licensed under the MIT License.