A professional ASP.NET Core Web API for restaurant menu management with JWT authentication and SQL Server database.
Project Structure (detailed view)
Appetit_ASP.NET_SQL_Server/
├── src/
│ └── RestaurantMenuAPI/
│ ├── Controllers/ # API controllers
│ ├── Data/ # EF Core DbContext, migrations
│ ├── DTOs/ # Data Transfer Objects
│ ├── Models/ # Entity models
│ ├── Services/ # Business logic
│ ├── Program.cs # App entry point
│ └── appsettings.json # Config
├── tests/
│ └── RestaurantMenuAPI.Tests/ # xUnit test project
├── Dockerfiles/ # Dockerfile.backend, Dockerfile.backend.tests
├── docker-compose.yml # Local dev
├── docker-compose.test.yml # Local/test
├── helm/ # Helm charts for K8s
├── .github/workflows/ # GitHub Actions CI/CD
├── docs/ # Project docs (see below)
├── README.md
└── ...
This project uses a robust GitHub Actions workflow to build, test, and deploy the API and SQL Server to Google Kubernetes Engine (GKE) using Helm. See the workflow in .github/workflows/deploy.yml.
Key Features:
- Automated Docker build and push to Google Artifact Registry
- Secure secret management via GitHub Secrets and Helm
- Helm-based deployment for both API and SQL Server
- Waits for SQL Server readiness before deploying API
- Health checks and HPA (Horizontal Pod Autoscaler) integration
- Load testing and scaling verification
Challenges & Solutions:
- YAML/Helm syntax: Fixed indentation, quoting, and linter issues for error-free deployment.
- Secret management: Ensured all sensitive values are injected via secrets, not hardcoded.
- Environment variable propagation: .NET does not expand
${VAR}inappsettings.json, so connection strings are built at runtime from env vars inProgram.cs. - Pod readiness: Added
/healthendpoint and tuned liveness/readiness probes for reliable startup. - Password consistency: Unified secret names for DB credentials across API and SQL Server.
- HPA testing: Automated load tests to verify autoscaling (see HPA Load Testing).
See also:
- Docker Desktop
- .NET 8.0 SDK (for development)
- Visual Studio 2022 or VS Code (optional)
-
Clone the repository
git clone <repository-url> cd RestaurantMenu
-
Start the application
docker-compose up --build
-
Access the API
- API: http://localhost:8080
- Swagger UI: http://localhost:8080/swagger
Before running the application, copy the example environment file and fill in your own secrets:
cp .env.example .env
# Then edit .env and set your database password, JWT secret, etc.Never commit your .env file to version control.
The application and Docker Compose will automatically use variables from your .env file for sensitive configuration (database credentials, JWT secret, etc.).
-
Install dependencies
dotnet restore
-
Update database connection (optional)
- Modify
appsettings.jsonif you want to use a different SQL Server instance
- Modify
-
Run the application
dotnet run
This project includes a comprehensive test suite that validates all core functionality of the Restaurant Menu API.
- Each test runs in a clean, seeded database. The test infrastructure resets and reseeds the database before every test, ensuring no test state leaks between tests.
- Seeding logic is shared with the main application and includes roles, admin user, and menu items.
- TestBase uses xUnit's
IAsyncLifetimeto guarantee per-test isolation.
chmod +x run-tests.sh
./run-tests.sh- Tests are executed one by one in a single, persistent Docker container for speed and reliability.
- The test container is kept alive for the duration of the test run, and the database is reset and reseeded before each test.
- Clear pass/fail output for each test is shown in the terminal.
# Build the test image
docker build -f Dockerfile.tests -t restaurant-api-tests .
# Start the test database and test container (keep-alive mode)
docker compose -f docker-compose.test.yml up -d --build
# Run a specific test (example)
docker exec <test-container-id> dotnet test tests/RestaurantMenuAPI.Tests/RestaurantMenuAPI.Tests.csproj --filter "FullyQualifiedName=YourTestName"- Comprehensive Coverage: Tests all major API components
- Docker Integration: Runs in containerized environment
- Per-Test Isolation: Database is reset and seeded before every test
- Clear Output: Green checkmarks and detailed test results
- Production Ready: Validates real-world functionality
🧪 Restaurant Menu API Integration Tests
==========================================
🔹 Basic Tests
✅ Simple_Math_Test_Should_Pass
✅ String_Test_Should_Pass
🔹 Data Seeding Tests
✅ Database_Should_BeSeeded_WithRoles
✅ Database_Should_BeSeeded_WithAdminUser
✅ Database_Should_BeSeeded_WithMenuItems
✅ Seeded_MenuItems_Should_HaveCorrectData
🔹 Identity Tests
✅ Identity_Services_Should_BeRegistered
✅ Password_Policy_Should_BeConfigured
✅ User_Options_Should_BeConfigured
🔹 Database Tests
✅ Database_Context_Should_BeConfigured
✅ Database_Should_BeAccessible
✅ Database_Should_HaveCorrectTables
🔹 API Startup Tests
✅ Api_Should_StartSuccessfully
✅ Api_Should_HandleInvalidRoutes
✅ Api_Should_ReturnCorrectContentType
🔹 Swagger Configuration Tests
✅ Swagger_Json_Should_BeAccessible
✅ Swagger_Should_ContainApiInformation
✅ Swagger_Should_HaveBearerSecurity
🔹 JWT Configuration Tests
✅ JWT_Configuration_Should_BeValid
✅ JWT_Bearer_Options_Should_BeConfigured
🔹 CORS Configuration Tests
✅ CORS_Should_BeConfigured
✅ CORS_Preflight_Should_BeHandled
📊 Test Results Summary:
Passed: 22/22 tests
Success Rate: 100%
🎉 All tests passed! Your Restaurant Menu API is working correctly.
-
Start the application:
docker-compose up --build
-
Run the comprehensive test suite:
./run-tests.sh
-
Access the live API:
- Open: http://localhost:8080
- Test endpoints using the interactive Swagger UI
The test suite validates ALL core functionality:
| Category | Test Methods | Count |
|---|---|---|
| Basic | Simple_Math_Test_Should_Pass, String_Test_Should_Pass | 2 |
| Data Seeding | Database_Should_BeSeeded_WithRoles, Database_Should_BeSeeded_WithAdminUser, Database_Should_BeSeeded_WithMenuItems, Seeded_MenuItems_Should_HaveCorrectData | 4 |
| Database | Database_Context_Should_BeConfigured, Database_Should_BeAccessible, Database_Should_HaveCorrectTables | 3 |
| Identity | Identity_Services_Should_BeRegistered, Password_Policy_Should_BeConfigured, User_Options_Should_BeConfigured | 3 |
| API Startup | Api_Should_StartSuccessfully, Api_Should_HandleInvalidRoutes, Api_Should_ReturnCorrectContentType | 3 |
| Swagger Configuration | Swagger_Json_Should_BeAccessible, Swagger_Should_ContainApiInformation, Swagger_Should_HaveBearerSecurity | 3 |
| JWT Configuration | JWT_Configuration_Should_BeValid, JWT_Bearer_Options_Should_BeConfigured | 2 |
| CORS Configuration | CORS_Should_BeConfigured, CORS_Preflight_Should_BeHandled | 2 |
Total: 22 tests covering all major components
Try these endpoints in Swagger UI:
-
Register a new user:
POST /api/auth/register { "email": "demo@test.com", "password": "Demo123!", "firstName": "Demo", "lastName": "User" }
-
Login and get JWT token:
POST /api/auth/login { "email": "demo@test.com", "password": "Demo123!" }
-
View menu items (no auth required):
GET /api/menu/items -
Create a reservation (auth required):
POST /api/reservations { "tableId": 1, "reservationDate": "2025-08-04", "reservationTime": "19:00:00", "partySize": 4, "customerName": "Demo Customer", "customerEmail": "demo@test.com", "customerPhone": "123-456-7890" }
✅ Security: JWT authentication with role-based authorization
✅ Scalability: Containerized with Docker Compose
✅ Reliability: Comprehensive test coverage (25+ tests)
✅ Maintainability: Clean architecture with service layer
✅ Documentation: Interactive Swagger API documentation
✅ Data Integrity: Entity Framework with proper relationships
✅ Error Handling: Global exception handling with proper HTTP status codes
- Docker Desktop installed
- Docker Compose available
-
Clone and navigate to the project directory
-
Build and run with Docker Compose:
docker-compose up --build
-
Access the application:
- API: http://localhost:8080
- Swagger UI: http://localhost:8080
- Database: localhost:1433
- restaurant-api: Main ASP.NET Core application
- sqlserver: SQL Server 2022 Express database
Key configuration options available via environment variables:
ConnectionStrings__DefaultConnection: Database connection stringJwtSettings__SecretKey: JWT signing keyJwtSettings__ExpiryMinutes: Token expiration time
The application includes configurable restaurant settings:
- Maximum reservations per day
- Maximum reservations per user
- Reservation time slot duration
- Restaurant operating hours
- Booking advance notice period
POST /api/auth/login- User loginPOST /api/auth/register- User registrationPOST /api/auth/change-password- Change passwordGET /api/auth/profile- Get user profile
GET /api/menu/categories- Get all categoriesPOST /api/menu/categories- Create category (Staff/Admin)GET /api/menu/items- Get menu itemsPOST /api/menu/items- Create menu item (Staff/Admin)PATCH /api/menu/items/{id}/availability- Update availability (Staff/Admin)
GET /api/reservations- Get reservationsPOST /api/reservations- Create reservationPUT /api/reservations/{id}- Update reservationDELETE /api/reservations/{id}- Cancel reservationGET /api/reservations/availability- Check availability
GET /api/tables- Get all tables (Staff/Admin)POST /api/tables- Create table (Admin)PUT /api/tables/{id}- Update table (Admin)
- JWT-based stateless authentication
- Role-based access control (Guest, Staff, Admin)
- Secure password requirements
- Token expiration and refresh
- SQL injection prevention via Entity Framework
- Input validation on all endpoints
- CORS configuration
- HTTPS enforcement in production
- Email: admin@restaurant.com
- Password: Admin123!
The application automatically seeds:
- User roles (Guest, Staff, Admin)
- Sample menu categories and items
- Restaurant tables (T01-T05)
- System configuration settings
- Structured logging with Serilog
- File-based logs with daily rolling
- Console output for development
- Request/response logging
- Database connection health checks
- Application startup diagnostics
- Error handling and reporting
# Build the Docker image
docker build -t restaurant-menu-api .
# Run with development settings
docker-compose -f docker-compose.yml up --build- Automatic database creation and seeding
- Entity Framework Core migrations
- Sample data population on startup
- Follow C# coding conventions
- Use async/await patterns
- Implement proper error handling
- Write comprehensive unit tests
- Create feature branch
- Implement changes with tests
- Update documentation
- Submit pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the repository
- Contact: kaanevran@gmail.com
Built with ❤️ using ASP.NET Core, Docker, Kubernetes, and modern DevOps practices

