A RESTful API for managing personal contacts, built with .NET 9, Entity Framework Core, and PostgreSQL. This project demonstrates clean architecture principles, repository pattern, and modern API development practices.
- Contact Management: Full CRUD operations for contacts with detailed information
- Organization: Group contacts and apply tags for better organization
- Search: Search contacts by name, email, phone, or company
- Pagination: Efficient data retrieval with pagination support
- Clean Architecture: Separation of concerns with Domain, Application, Infrastructure, and API layers
- Repository Pattern: Abstracted data access with Unit of Work pattern
- PostgreSQL Database: Using Npgsql provider with Entity Framework Core
- Health Checks: Built-in health and readiness endpoints
- .NET 9.0: Latest framework for high-performance APIs
- Entity Framework Core 9.0: Code-first ORM with migrations
- PostgreSQL: Open-source relational database
- xUnit: Unit testing framework
- C# 13: With nullable reference types enabled
MyOpenTelemetryApi/
├── src/
│ ├── MyOpenTelemetryApi.Api/ # Web API controllers and configuration
│ ├── MyOpenTelemetryApi.Domain/ # Domain entities and interfaces
│ ├── MyOpenTelemetryApi.Application/ # Business logic and DTOs
│ └── MyOpenTelemetryApi.Infrastructure/ # Data access and external services
├── tests/
│ ├── MyOpenTelemetryApi.Api.Tests/
│ ├── MyOpenTelemetryApi.Application.Tests/
│ └── MyOpenTelemetryApi.Infrastructure.Tests/
└── MyOpenTelemetryApi.sln
- .NET 9.0 SDK or later
- PostgreSQL database
- Entity Framework Core tools:
dotnet tool install --global dotnet-ef
-
Clone the repository
git clone <repository-url> cd MyOpenTelemetryApi
-
Configure the database connection
For development, use user secrets to store the connection string:
cd src/MyOpenTelemetryApi.Api dotnet user-secrets init dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Host=your-host;Database=your-db;Username=your-user;Password=your-password;SSL Mode=Require" cd ../..
For production, use environment variables:
export ConnectionStrings__DefaultConnection="Host=your-host;Database=your-db;Username=your-user;Password=your-password;SSL Mode=Require"
-
Apply database migrations
dotnet ef database update --project src/MyOpenTelemetryApi.Infrastructure --startup-project src/MyOpenTelemetryApi.Api
-
Run the API
dotnet run --project src/MyOpenTelemetryApi.Api
GET /api/contacts?pageNumber=1&pageSize=20
- Get paginated contactsGET /api/contacts/{id}
- Get contact with full detailsGET /api/contacts/search?q=searchterm
- Search contactsGET /api/contacts/group/{groupId}
- Get contacts by groupGET /api/contacts/tag/{tagId}
- Get contacts by tagPOST /api/contacts
- Create new contactPUT /api/contacts/{id}
- Update contactDELETE /api/contacts/{id}
- Delete contact
GET /api/groups
- Get all groupsGET /api/groups/{id}
- Get group by IDPOST /api/groups
- Create new groupPUT /api/groups/{id}
- Update groupDELETE /api/groups/{id}
- Delete group
GET /api/tags
- Get all tagsGET /api/tags/{id}
- Get tag by IDPOST /api/tags
- Create new tagPUT /api/tags/{id}
- Update tagDELETE /api/tags/{id}
- Delete tag
GET /api/health
- Basic health checkGET /api/health/ready
- Readiness check with migration status
POST /api/contacts
{
"firstName": "John",
"lastName": "Doe",
"company": "Acme Corp",
"emailAddresses": [
{
"email": "[email protected]",
"type": "Work",
"isPrimary": true
}
],
"phoneNumbers": [
{
"number": "+1-555-123-4567",
"type": "Mobile",
"isPrimary": true
}
]
}
POST /api/groups
{
"name": "Friends",
"description": "Personal friends and family"
}
POST /api/tags
{
"name": "VIP",
"colorHex": "#FF0000"
}
dotnet test
dotnet ef migrations add MigrationName --project src/MyOpenTelemetryApi.Infrastructure --startup-project src/MyOpenTelemetryApi.Api --output-dir Data/Migrations
dotnet publish -c Release -o ./publish
- Clean Architecture: Ensures separation of concerns and testability
- Repository Pattern with Unit of Work: Provides abstraction over data access
- DTOs: Separate data transfer objects from domain entities
- Manual Mapping: No dependency on AutoMapper for simple, explicit mapping
- FOSS Only: Uses only free and open-source libraries
- Minimal Dependencies: Avoids unnecessary packages to reduce complexity
This project is open source and available under the AGPL license.
Notice: This project contains code generated by Large Language Models such as Claude and Gemini. All code is experimental whether explicitly stated or not.