Minimal Spring Boot-based RESTful CRUD service managing a user profile entity. Includes OpenAPI/Swagger UI, Liquibase migrations, Actuator, Prometheus metrics, and optional local Docker stack for Postgres, Prometheus, Grafana, and SonarQube.
- Language/Runtime: Java 21
- Frameworks: Spring Boot (Web, Data JPA, Actuator), Springdoc OpenAPI, Undertow
- Persistence: PostgreSQL (Liquibase migrations), H2 for tests
- Observability: Micrometer + Prometheus, Logback (plain/JSON), Grafana dashboards
- Quality: JUnit 5, Mockito, Hamcrest, JaCoCo (80%+), Qulice
- Java 21+
- Git
- Docker (optional, for local infra and monitoring)
- An IDE (IntelliJ IDEA recommended)
- Clone and enter the project
git clone https://github.com/IQKV/quickstart-mvc-rest-user-profile-crud.git
cd quickstart-mvc-rest-user-profile-crud- Start Postgres (choose one)
- Existing Postgres: set env vars (see Configuration) and ensure DB is reachable
- Docker:
docker compose -f compose.yaml up -d postgres
- Run the app
./mvnw spring-boot:run -Dspring-boot.run.profiles=local -P dev- Explore the API
- Swagger UI:
http://localhost:8080/swagger-ui.html - OpenAPI JSON:
http://localhost:8080/v3/api-docs - Actuator Health:
http://localhost:8080/actuator/health - Prometheus metrics:
http://localhost:8080/actuator/prometheus
To build a runnable jar:
./mvnw package
java -jar target/*.jarKey application properties (defaults in src/main/resources/application.yml):
- Server:
SERVER_PORT(default 8080) - Datasource:
DATASOURCE_URL(defaultjdbc:postgresql://localhost:5432/svc_testing_db)DATASOURCE_USERNAME(defaultpostgres)DATASOURCE_PASSWORD(defaultpostgres)DATASOURCE_DRIVER(defaultorg.postgresql.Driver)
- Management:
MANAGEMENT_SERVER_PORT(default 8080)
Local developer-friendly settings are enabled via the local Spring profile (application-local.yml): SQL logged, caches off, actuator endpoints exposed.
Base path: http://localhost:8080/api/v1/user-profiles
- Create
curl -sS -X POST http://localhost:8080/api/v1/user-profiles \
-H "Content-Type: application/json" \
-d '{"email":"john.doe@example.com","active":true}'- Get by id
curl -sS http://localhost:8080/api/v1/user-profiles/1- List (optional filter by
email)
curl -sS "http://localhost:8080/api/v1/user-profiles?email=john"- Update
curl -sS -X PUT http://localhost:8080/api/v1/user-profiles/1 \
-H "Content-Type: application/json" \
-d '{"email":"johnny@example.com","active":false}'- Delete by id
curl -sS -X DELETE http://localhost:8080/api/v1/user-profiles/1- Delete all
curl -sS -X DELETE http://localhost:8080/api/v1/user-profiles- List active
curl -sS http://localhost:8080/api/v1/user-profiles/activecompose.yaml includes optional services for local development:
- postgres: Postgres 16 (exposes 5432)
- prometheus: scrapes app metrics; uses host network for easy local testing
- grafana: pre-provisioned dashboards; default admin password
changeme - sonar: SonarQube Community (ports 9000/9001 bound to localhost)
Start all:
docker compose up -dServices:
- Prometheus config:
docker/prometheus/prometheus.yml - Grafana provisioning:
docker/grafana/provisioning/
Note for macOS: remove network_mode: host in compose.yaml and replace localhost with host.docker.internal in Prometheus and Grafana datasources as hinted in comments.
- Open the project via
pom.xml - Activate Spring profile
localin your Run Configuration (or setSPRING_PROFILES_ACTIVE=local) - Run the application; visit Swagger UI at
http://localhost:8080/swagger-ui.html
- Run unit tests with coverage and style checks:
./mvnw verify -Puse-quliceJaCoCo rules require at least 80% coverage overall and per-class thresholds (see pom.xml). You may also use the use-testcontainers profile to leverage ephemeral Postgres in tests:
./mvnw test -Puse-testcontainersThe code follows the Google Java Style Guide and is checked by:
- SonarQube, PMD, Checkstyle, SpotBugs, Qulice
- Cannot connect to DB: verify Postgres is running and
DATASOURCE_*env vars match the instance - Port conflicts: change
SERVER_PORTor stop conflicting services - macOS networking with Docker monitoring: see the note above regarding
network_mode: host
Licensed under the Apache License, Version 2.0. See LICENSE.