A production-ready REST API for a quiz game application built with Spring Boot 4.0, PostgreSQL, and Flyway for database migrations. The application is containerized and deployed to Azure Container Apps using Terraform for infrastructure as code.
- Backend: Spring Boot 4.0 (Java 21)
- Database: PostgreSQL with Flyway migrations
- Infrastructure: Azure Container Apps, Azure Container Registry, Azure Database for PostgreSQL
- CI/CD: GitHub Actions with automated testing and deployment
- IaC: Terraform for Azure infrastructure provisioning
- Docker and Visual Studio Code with the Dev Containers extension
- OR Java 21, Maven 3.9+, and PostgreSQL 16+ (for non-containerized development)
- Azure CLI (for deployment)
- Terraform 1.6+ (for infrastructure)
This repository includes a complete Dev Container configuration that automatically sets up Java 21, Maven, and PostgreSQL 17.
-
Clone the repository
git clone https://github.com/daveginncom/quiz-game-backend.git cd quiz-game-backend -
Open in Dev Container
- Open the folder in VS Code
- Click the notification to "Reopen in Container" (or use Command Palette:
Dev Containers: Reopen in Container) - Wait for the container to build and start (first time takes a few minutes)
-
PostgreSQL is already running!
- The Dev Container automatically starts PostgreSQL 17
- Connection details:
- Host:
postgresdb - Port:
5432 - Database:
postgres - User:
postgres - Password:
postgres
- Host:
-
Run the application
cd quizapp ./mvnw spring-boot:run -
Test the API
curl http://localhost:8080/api/quizzes
If you're not using Dev Containers but want to run PostgreSQL in Docker:
docker run --name quiz-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=postgres \
-p 5432:5432 \
-d postgres:17Then update quizapp/src/main/resources/application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgresThe application will automatically:
- Create the database schema via Flyway migrations
- Insert sample quiz data
- Start the REST API on port 8080
quiz-game-backend/
โโโ .github/workflows/ # GitHub Actions CI/CD workflows
โโโ infra/ # Terraform infrastructure code
โโโ quizapp/ # Spring Boot application
โ โโโ src/
โ โ โโโ main/
โ โ โ โโโ java/ # Application source code
โ โ โ โโโ resources/
โ โ โ โโโ db/migration/ # Flyway SQL migrations
โ โ โโโ test/ # Unit and integration tests
โ โโโ Dockerfile # Container image definition
โ โโโ pom.xml # Maven dependencies
โโโ README.md # This file
- Application Setup Guide - Complete setup walkthrough with Flyway configuration
- Database Guide - PostgreSQL setup, schema, and migration workflow
- Flyway Migration Guide - Migration file naming conventions and best practices
- Spring Boot Reference - Official Spring Boot documentation links
- Infrastructure Guide - Terraform setup, Azure resources, and deployment instructions
- CI/CD Workflows - GitHub Actions setup, secrets configuration, and troubleshooting
The project includes comprehensive test coverage across all layers:
- Unit Tests: Service layer with Mockito mocks (8 tests)
- Integration Tests:
- REST API endpoints with MockMvc (8 tests)
- Repository/JPA operations with H2 (8 tests)
Run tests locally:
cd quizapp
./mvnw testTest execution:
- โ Runs automatically on pull requests (prevents merging failing tests)
- โ Runs before deployment to main branch
- โ Uses H2 in-memory database with PostgreSQL compatibility mode
All database schema changes are managed through Flyway versioned migrations:
- quizzes - Quiz metadata (title, timestamps)
- questions - Questions linked to quizzes (text, order)
- choices - Multiple choice answers (text, correct flag, order)
- Create
V{number}__{description}.sqlinquizapp/src/main/resources/db/migration/ - Write your SQL changes
- Restart the application - Flyway runs automatically
Example:
-- V3__Add_quiz_categories.sql
ALTER TABLE quizzes ADD COLUMN category VARCHAR(100);
CREATE INDEX idx_quizzes_category ON quizzes(category);See the Flyway Guide for detailed migration instructions.
Pushing to the main branch triggers automatic deployment:
- Tests run - All unit and integration tests must pass
- Infrastructure provisioned - Terraform creates/updates Azure resources
- Docker image built - Application packaged and pushed to Azure Container Registry
- Database migrated - Flyway migrations run against Azure PostgreSQL
- Application deployed - Container App updated with new image
See the Infrastructure Guide for step-by-step manual deployment instructions.
Configure these in GitHub repository settings:
AZURE_CREDENTIALS- Azure service principal JSONPOSTGRES_ADMIN_PASSWORD- PostgreSQL admin password
See CI/CD Workflows for detailed secret setup.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/quizzes |
Get all quizzes with questions and choices |
| GET | /api/quizzes/{id} |
Get specific quiz by ID |
| POST | /api/quizzes |
Create a new quiz |
| PUT | /api/quizzes/{id} |
Update an existing quiz |
| DELETE | /api/quizzes/{id} |
Delete a quiz |
Example Response:
{
"id": 1,
"title": "British America Quiz",
"questions": [
{
"id": 1,
"question": "What were the original 13 colonies primarily located along?",
"questionOrder": 1,
"choices": [
{
"id": 1,
"text": "The Atlantic Coast",
"correct": true,
"choiceOrder": 1
}
]
}
]
}- Framework: Spring Boot 4.0 (Spring MVC, Spring Data JPA)
- Language: Java 21 (LTS)
- Database: PostgreSQL 16
- Migrations: Flyway 10.x
- Build Tool: Maven 3.9+
- Testing: JUnit 5, Mockito, AssertJ, H2
- Containerization: Docker, Azure Container Apps
- Infrastructure: Terraform, Azure (ACR, PostgreSQL Flexible Server, Container Apps, Log Analytics)
- CI/CD: GitHub Actions
Approximate Azure monthly costs for low-traffic deployment:
- Azure Container Registry (Basic): ~$5
- PostgreSQL Flexible Server (B1ms): ~$12
- Container Apps (pay-per-use): ~$5-20
- Log Analytics (5GB free, then $2.30/GB): ~$0-5
Total: ~$25-40/month
See Infrastructure Guide for cost optimization tips.
- PostgreSQL connections require SSL
- Secrets stored in Azure Container App environment
- Firewall rules restrict database access
- GitHub Actions uses service principal with limited permissions
- Tests run on pull requests to prevent merging broken code
See CI/CD Security Best Practices for production hardening.
- Create a feature branch from
main - Make your changes
- Add tests for new functionality
- Open a pull request (tests will run automatically)
- Merge after approval and passing tests
This project is for educational/demonstration purposes.
- Dev Container won't start: Ensure Docker Desktop is running and you have the Dev Containers extension installed
- PostgreSQL won't connect: In Dev Container, use host
postgresdb. Outside Dev Container, uselocalhost - Migrations fail: The database is automatically created by the Dev Container. Check application.properties has correct connection details
- Tests fail: Ensure H2 is in test dependencies and
@ActiveProfiles("test")is present - Port 8080 already in use: Stop other applications or change the port in application.properties
- Terraform fails: Verify Azure credentials and check Infrastructure Guide
- Container won't start: Check logs in Azure Portal or use
az containerapp logs show - Database connection fails: Verify firewall rules and connection string
See specific troubleshooting sections in:
- Database Guide for database issues
- Infrastructure Guide for Azure deployment issues
- CI/CD Workflows for GitHub Actions problems
For issues and questions, please open a GitHub issue in this repository.