A HTTP REST API in C# ASP.NET Core Web (.NET 8) to record and query simple rain logs per user. The API stores users and their rain observations (timestamp, rain true/false, optional latitude/longitude) in a PostgreSQL database and exposes endpoints to create and retrieve logs. Swagger UI and example requests are included.
Repository: https://github.com/ericrangels/RainTrackingApi
- POST
/api/data— create a rain log for a user (creates user if missing) - GET
/api/data— fetch a user's rain logs (supports optionalrainquery filter) - Swagger UI with enhanced documentation and examples at
/swagger - Custom validation error schemas with detailed error messages
- Uses EF Core with
RainTrackingDbContext(PostgreSQL) - AutoMapper for DTO ↔ domain mappings
- Simple repository + service layering
All platforms (Windows, macOS, Linux):
- Docker Desktop 4.0+ or Docker Engine 20.10+
- Docker Compose 2.0+ (included with Docker Desktop)
- Git 2.25+ (for cloning and version control)
Note: All commands in this guide work on Windows, macOS, and Linux. Use Terminal on macOS/Linux or PowerShell/Command Prompt on Windows.
What you DON'T need to install locally:
- .NET 8 SDK (runs in Docker container)
- PostgreSQL (runs in Docker container)
- Entity Framework tools (installed in Docker container)
git clone https://github.com/ericrangels/RainTrackingApi.git
cd RainTrackingApicd RainTrackingApidocker-compose up --buildThis will:
- Build the .NET 8 API Docker image using the included Dockerfile
- Start a PostgreSQL database container (
raindb) - Install Entity Framework tools in the container
- Expose the API on
http://localhost:5000
Open a new terminal window, don't forget to navigate to the API directory:
cd RainTrackingApiRun the migration command:
docker-compose exec api sh -c "cd /src && dotnet ef database update"This creates the necessary database tables (User and UserRainLog).
- Swagger UI: http://localhost:5000/swagger
- API Base: http://localhost:5000/api/data
docker-compose downTo remove all data (including the database):
docker-compose down -vAll endpoints require the x-userId header.
curl -X POST http://localhost:5000/api/data \
-H "Content-Type: application/json" \
-H "x-userId: user-123" \
-d '{
"rain": true,
"latitude": 51.5074,
"longitude": -0.1278
}'Response (201 Created):
{
"timestamp": "2025-10-18T12:34:56Z",
"rain": true,
"userIdentifier": "user-123",
"latitude": 51.5074,
"longitude": -0.1278
}curl -H "x-userId: user-123" http://localhost:5000/api/dataOptional filter by rain status:
curl -H "x-userId: user-123" "http://localhost:5000/api/data?rain=true"Response (200 OK):
[
{
"timestamp": "2025-10-18T12:34:56Z",
"rain": true,
"userIdentifier": "user-123",
"latitude": 51.5074,
"longitude": -0.1278
}
]The API returns detailed validation errors when requests fail validation:
# Example: Missing x-userId header
curl -X POST http://localhost:5000/api/data \
-H "Content-Type: application/json" \
-d '{"rain": true}'Error Response (400 Bad Request):
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"x-userId": [
"The userIdentifier field is required.",
"The field must contain a non-empty, non-whitespace value."
]
},
"traceId": "00-aee3f44db62908e94ed36f931970eaa1-46313aea3590f79c-00"
}The docker-compose.yml uses these defaults:
-
PostgreSQL:
- Database:
raindb - User:
rainuser - Password:
rainpass - Port:
5432
- Database:
-
API:
- Host port:
5000(mapped to container port8080) - Container port:
8080(.NET 8 default) - Connection string:
Host=db;Database=raindb;Username=rainuser;Password=rainpass - Built from local Dockerfile (includes EF Core tools for migrations)
- Host port:
Note: The docker-compose.yml file uses the modern format without the deprecated version field, compatible with Docker Compose v1.27+ and v2.x.
Wait a few seconds for PostgreSQL to fully start, then retry:
docker-compose exec api sh -c "cd /src && dotnet ef database update"Ensure Docker Desktop is running before executing any docker-compose commands. On macOS, check that Docker Desktop is running in the menu bar.
Change the port in docker-compose.yml:
ports:
- "5001:8080" # Use port 5001 insteaddocker-compose logs api
docker-compose logs dbdocker-compose down -v
docker-compose up --build
docker-compose exec api sh -c "cd /src && dotnet ef database update"RainTrackingApi/
├── RainTrackingApi/
│ ├── Controllers/ # API endpoints
│ ├── Services/ # Business logic layer
│ │ └── Interfaces/ # Service interfaces
│ ├── Repositories/ # Data access layer
│ │ └── Interfaces/ # Repository interfaces
│ ├── Models/
│ │ ├── Domain/ # Database entities (User, UserRainLog)
│ │ ├── DTO/ # Data transfer objects
│ │ ├── Request/ # API request models
│ │ └── Response/ # API response models
│ ├── Data/ # EF Core DbContext
│ ├── Migrations/ # Database migrations
│ ├── Mappings/ # AutoMapper profiles
│ ├── Validation/ # Custom validation attributes
│ ├── Swagger/ # Swagger configuration & examples
│ │ └── Examples/ # Swagger example schemas
│ ├── Properties/ # Launch settings
│ ├── Program.cs # Application startup
│ ├── appsettings.json # Application configuration
│ ├── appsettings.Development.json # Development configuration
│ ├── Dockerfile # Docker build configuration
│ └── docker-compose.yml # Docker services configuration
├── RainTrackingApi.Tests/ # Unit tests
│ ├── Controllers/ # Controller tests
│ └── Services/ # Service tests
├── RainTrackingApi.sln # Solution file
└── README.md # This file
MIT License - see repository for details.