A comprehensive RESTful API for managing New Zealand walking trails and regions. Built with ASP.NET Core 8.0, featuring JWT authentication, role-based authorization, local image storage, and modern development practices.
- Features
- Architecture
- Tech Stack
- Getting Started
- API Documentation
- Database Schema
- Authentication & Authorization
- Project Structure
- Development
- Contributing
- License
- π JWT Authentication - Secure user authentication with 10-minute token expiration
- π₯ Role-Based Authorization - Reader and Writer roles with granular permissions
- ποΈ Walk Management - CRUD operations for walking trails with advanced filtering and pagination
- πΊοΈ Region Management - Manage New Zealand regions with associated walks
- πΈ Local Image Storage - Secure image upload with validation (JPG, PNG, max 10MB)
- π Advanced Filtering - Search walks by name, sort by criteria, and paginate results
- π‘οΈ Security - Input validation, model validation, and comprehensive error handling
- π Structured Logging - Serilog integration with file and console output
- π Interactive Documentation - Swagger/OpenAPI with JWT authentication support
- ποΈ Clean Architecture - Repository pattern, dependency injection, and separation of concerns
- β‘ Custom Middleware - Global exception handling with unique error tracking
The application follows clean architecture principles with:
- Controllers Layer - Handle HTTP requests and responses with role-based authorization
- Repository Layer - Data access abstraction with repository pattern
- Domain Models - Core business entities (Region, Walk, Difficulty, Image)
- DTOs - Data transfer objects for API contracts
- Custom Middleware - Global exception handling and error tracking
- Custom Filters - Model validation and request processing
| Technology | Version | Purpose |
|---|---|---|
| .NET 8.0 | Latest | Runtime and framework |
| ASP.NET Core | 8.0 | Web API framework |
| Entity Framework Core | 8.0 | ORM and database access |
| SQL Server | 2022 | Primary database |
| ASP.NET Core Identity | 8.0 | User authentication and authorization |
| JWT Bearer | 8.0 | Token-based authentication (10-min expiry) |
| AutoMapper | 12.0.1 | Object-to-object mapping |
| Serilog | 3.1.1 | Structured logging (file + console) |
| Swagger/OpenAPI | 6.5.0 | API documentation |
- .NET 8.0 SDK
- SQL Server (LocalDB or Express)
- Visual Studio 2022 or VS Code
-
Clone the repository
git clone https://github.com/yourusername/NZWalks.git cd NZWalks -
Configure the database
- Update connection strings in
appsettings.json:
"ConnectionStrings": { "NZWalksConnectionString": "Server=localhost;Database=NZWalksDb;Trusted_Connection=true;TrustServerCertificate=true", "NZWalksAuthConnectionString": "Server=localhost;Database=NZWalksAuthDb;Trusted_Connection=true;TrustServerCertificate=true" }
- Update connection strings in
-
Run database migrations
cd NZWalks.API dotnet ef database update -
Configure JWT settings
- Update JWT configuration in
appsettings.json:
"Jwt": { "Key": "your-secret-key-here", "Issuer": "https://localhost:7044/", "Audience": "https://localhost:7044" }
- Update JWT configuration in
-
Run the application
dotnet run
-
Access the API
- API:
https://localhost:7044 - Swagger Documentation:
https://localhost:7044/swagger
- API:
https://localhost:7044
| Method | Endpoint | Description | Authorization |
|---|---|---|---|
POST |
/auth/register |
Register a new user | Public |
POST |
/auth/login |
Authenticate user and get JWT token | Public |
| Method | Endpoint | Description | Authorization |
|---|---|---|---|
GET |
/regions |
Get all regions | Public |
GET |
/regions/{id} |
Get region by ID | Reader, Writer |
POST |
/regions |
Create new region | Writer |
PUT |
/regions/{id} |
Update region | Writer |
DELETE |
/regions/{id} |
Delete region | Writer |
| Method | Endpoint | Description | Authorization |
|---|---|---|---|
GET |
/walks |
Get all walks (with filtering) | Public |
GET |
/walks/{id} |
Get walk by ID | Public |
POST |
/walks |
Create new walk | Public |
PUT |
/walks/{id} |
Update walk | Public |
DELETE |
/walks/{id} |
Delete walk | Public |
| Method | Endpoint | Description | Authorization |
|---|---|---|---|
POST |
/images/upload |
Upload image (max 10MB, JPG/PNG) | Public |
The walks endpoint supports advanced filtering:
name- Filter walks by name (partial match)sortBy- Sort by field (name, length, etc.)isAscending- Sort direction (true/false)pageNumber- Page number for pagination (default: 1)pageSize- Number of items per page (default: 10)
Example:
GET /walks?name=mountain&sortBy=length&isAscending=false&pageNumber=1&pageSize=10
public class Region
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string? RegionImageUrl { get; set; }
}public class Walk
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public double LengthInKm { get; set; }
public string? WalkImgUrl { get; set; }
public Guid DifficultyId { get; set; }
public Guid RegionId { get; set; }
// Navigation Properties
public Difficulty Difficulty { get; set; }
public Region Region { get; set; }
}public class Difficulty
{
public Guid Id { get; set; }
public string Name { get; set; }
}public class Image
{
public Guid Id { get; set; }
public IFormFile File { get; set; }
public string FileName { get; set; }
public string? FileDescription { get; set; }
public string FileExtension { get; set; }
public long FileSizeInBytes { get; set; }
public string FilePath { get; set; }
}- Expiration: 10 minutes
- Algorithm: HMAC SHA256
- Claims: Email, Roles (Reader, Writer)
| Role | Permissions |
|---|---|
| Reader | Read access to regions (by ID) |
| Writer | Full CRUD access to regions |
Note: Walks endpoints are currently public (no authorization required)
- Register - Create a new user account with roles
- Login - Authenticate and receive JWT token
- Authorize - Include token in Authorization header:
Bearer {token}
NZWalks/
βββ NZWalks.API/ # Main API project
β βββ Controllers/ # API controllers
β β βββ AuthController.cs # Authentication endpoints
β β βββ RegionsController.cs # Region management (role-based auth)
β β βββ WalksController.cs # Walk management (public)
β β βββ ImagesController.cs # Image upload (public)
β βββ Data/ # Database contexts
β β βββ NZWalksDBContext.cs # Main database context
β β βββ NZWalksAuthDbContext.cs # Authentication context
β βββ Models/ # Domain models and DTOs
β β βββ Domain/ # Entity models
β β βββ DTOs/ # Data transfer objects
β βββ Repositories/ # Data access layer
β β βββ IRegionRepository.cs
β β βββ IWalkRepository.cs
β β βββ IImageRepository.cs
β β βββ SQL implementations
β βββ Mappings/ # AutoMapper profiles
β βββ Middlewares/ # Custom middleware
β β βββ ExceptionHandlerMiddleware.cs # Global error handling
β βββ CustomActionFilters/ # Custom validation filters
β β βββ ValidateModelAttribute.cs # Model validation
β βββ Migrations/ # Entity Framework migrations
βββ README.md
# Set environment to development
set ASPNETCORE_ENVIRONMENT=Development
# Run the application
dotnet run# Create a new migration
dotnet ef migrations add MigrationName
# Update database
dotnet ef database update
# Remove last migration
dotnet ef migrations remove-
Using Swagger UI
- Navigate to
https://localhost:7044/swagger - Authenticate using the
/auth/loginendpoint - Copy the JWT token and click "Authorize"
- Test other endpoints
- Navigate to
-
Using HTTP Client
- Import the
NZWalks.API.httpfile into your IDE - Configure environment variables for base URL
- Execute requests directly from the file
- Import the
- Supported Formats: JPG, JPEG, PNG
- Maximum Size: 10MB
- Storage: Local file system in
Images/directory - Validation: Automatic file type and size validation
- Global Exception Middleware: Catches all unhandled exceptions
- Unique Error IDs: Each error gets a GUID for tracking
- Structured Logging: Errors logged with Serilog
- Custom Error Response: Consistent error format
The application uses Serilog for structured logging:
- Console Output: For development debugging
- File Logging: Daily rotation in
Logs/directory - Log Level: Information and above
- Format: Structured JSON logging
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow C# coding conventions
- Add appropriate XML documentation
- Include unit tests for new features
- Update API documentation
- Ensure all tests pass before submitting PR
- Test image upload functionality with various file types
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with ASP.NET Core 8.0
- Inspired by New Zealand's beautiful walking trails
- Uses modern development practices and patterns
- Implements secure authentication and authorization
Made with β€οΈ for the New Zealand walking community