A REST API built with Spring Boot that fetches users from DummyJSON Users API and stores them in PostgreSQL.
- Java 25+
- Docker Desktop
- Maven (wrapper included)
# 1. Clone
git clone https://github.com/XPEHO/spring_boot_java_random_user.git
cd spring_boot_java_random_user
# 2. Configure environment
cp .env.template .env
# Edit .env with your credentials
# 3. Start PostgreSQL
docker-compose up -d
# 4. Run application
./mvnw spring-boot:runAccess:
- Swagger UI: http://localhost:8080/api
- Health Check: http://localhost:8080/actuator/health
POSTGRES_USER=your_user
POSTGRES_PASSWORD=your_password
POSTGRES_DB=your_database
POSTGRES_PORT=5432application.properties uses:
dummy.api.base-url=https://dummyjson.com/- default: PostgreSQL (production)
- local: Custom local settings
- test: H2 in-memory database
Interactive Docs: http://localhost:8080/api
OpenAPI Spec: http://localhost:8080/v3/api-docs
| Method | Path | Description | Status |
|---|---|---|---|
GET |
/random-users?page=1&size=10&source=DUMMY |
Fetch and save users from selected external API source | ✅ |
GET |
/random-users/{id} |
Get user by ID | ✅ |
POST |
/random-users |
Create a new user | ✅ |
PUT |
/random-users/{id} |
Update user | ✅ |
DELETE |
/random-users/{id} |
Delete user | ✅ |
GET |
/random-users/filter |
Filter users by criteria | ✅ |
# Fetch 10 users from external API and store them
curl -X GET "http://localhost:8080/random-users?page=1&size=10&source=DUMMY"
# Fetch 10 users from randomuser.me and store them
curl -X GET "http://localhost:8080/random-users?page=1&size=10&source=RANDOM_USER"
# Get user by ID
curl -X GET "http://localhost:8080/random-users/1"
# Create user
curl -X POST "http://localhost:8080/random-users" \
-H "Content-Type: application/json" \
-d '{
"gender": "female",
"firstname": "Jane",
"lastname": "Doe",
"civility": "Ms",
"email": "jane@example.com",
"phone": "0600000000",
"picture": "pic.jpg",
"nat": "FR"
}'
# Filter users by gender and nationality
curl -X GET "http://localhost:8080/random-users/filter?gender=MALE&nat=FR"
# Filter users by firstname (partial match, case-insensitive)
curl -X GET "http://localhost:8080/random-users/filter?firstname=john"
# Update user
curl -X PUT "http://localhost:8080/random-users/1" \
-H "Content-Type: application/json" \
-d '{
"gender": "male",
"firstname": "John",
"lastname": "Smith",
"civility": "Mr",
"email": "john@example.com",
"phone": "0611111111",
"picture": "pic2.jpg",
"nat": "US"
}'# Run all tests with Docker
./mvnw verify
# Unit tests only
./mvnw test
# With coverage report (target/site/jacoco/index.html)
./mvnw clean verify
#cucumber tests
./mvnw verify -DskipDocker=true -Dit.test=CucumberIntegrationTestTest Stack:
- JUnit 5 - Testing framework
- Mockito - Mocking
- JaCoCo - Code coverage
- Cucumber - BDD
┌─────────────────────────────────────┐
│ Presentation Layer │ ← REST Controllers
│ (controllers, handlers) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Domain Layer │ ← Business Logic
│ (usecases, entities, exceptions) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Data Layer │ ← Data Access
│ (repositories, services, sources) │
└─────────────────────────────────────┘
↓
PostgreSQL
LocalUserService: local persistence operations (save, read, delete) backed by PostgreSQL.RemoteUserService: external user source contract used by use cases.
DummyUserApi: Retrofit client contract for DummyJSON endpoints.DummyUserServiceImpl: adapter that callsDummyUserApi, maps DTOs, and returnsPaginatedUsers.RandomUserApi: Retrofit client contract for randomuser.me endpoints.RandomUserServiceImpl: adapter that callsRandomUserApi, maps DTOs, and returnsPaginatedUsers.
src/main/java/com/xpeho/spring_boot_java_random_user/
├── SpringBootJavaRandomUserApplication.java ← Entry point
├── config/ ← Configuration
├── presentation/ ← REST API Layer
│ ├── controllers/ ← API interfaces
│ └── handlers/ ← Implementations
├── domain/ ← Business Layer
│ ├── entities/ ← Domain models
│ ├── exceptions/ ← Custom exceptions
│ ├── services/ ← Business services
│ └── usecases/ ← Use cases
└── data/ ← Data Layer
├── converters/ ← DTO/Entity mapping
├── models/ ← Data models
├── services/ ← Data services
└── sources/ ← API & DB access
| Column | Type | Description |
|---|---|---|
id |
SERIAL PRIMARY KEY | Auto-incremented identifier |
gender |
VARCHAR(20) | Gender |
firstname |
VARCHAR(100) | First name |
lastname |
VARCHAR(100) | Last name |
civility |
VARCHAR(20) | Title (Mr, Ms, Mrs, etc.) |
email |
VARCHAR(255) | Email address |
phone |
VARCHAR(50) | Phone number |
picture |
VARCHAR(500) | Avatar/picture URL |
nat |
VARCHAR(10) | Nationality code |
Database schema is managed with Liquibase. Migrations are applied automatically on application startup.
src/main/resources/db/changelog/
├── db.changelog-master.yaml ← Index file
└── changes/
└── 001-create-users-table.yaml ← Table creation
CLI Commands:
./mvnw liquibase:status # View pending changes
./mvnw liquibase:update # Apply migrations
./mvnw liquibase:rollback -Dliquibase.rollbackCount=1 # Rollback last change- Health Check: http://localhost:8080/actuator/health
- All Endpoints: http://localhost:8080/actuator
- Metrics: http://localhost:8080/actuator/metrics
Available Metrics: JVM metrics, HTTP metrics, Database connection pool metrics
./mvnw clean verify sonar:sonarWorkflow: .github/workflows/sonar.yaml
Triggers: Push to any branch, Pull requests
Pipeline:
- Sets up Java 25
- Runs Maven tests with code coverage
- Uploads results to SonarQube
- Waits for quality gate
Required Secrets:
SONAR_TOKEN- SonarQube authenticationSONAR_HOST_URL- SonarQube instance URLPOSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB,POSTGRES_PORT
Error:
Failed to configure a DataSource: 'url' attribute is not specified
and no embedded datasource could be configured.
Solution:
Ensure spring.datasource.url is set in application.properties or environment variables.
Error:
org.postgresql.util.PSQLException: Connection to localhost:5432 refused
Solution:
# Check if Docker is running
docker ps
# Start PostgreSQL
docker-compose up -d
# Verify connection
psql -U postgres -h localhostError:
Circular placeholder reference in application-test.properties
Solution:
Use the corrected application-test.properties with H2 configuration:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.DriverError:
error: release version 25 not supported
Solution:
- Install Java 25 or later
- Update Maven compiler plugin version in
pom.xml
This project integrates with DummyJSON Users API:
- Base URL: https://dummyjson.com/
- Users Endpoint: https://dummyjson.com/users
- Documentation: https://dummyjson.com/docs/users
- Features:
- Paginated user retrieval (
limit,skip) - Stable JSON schema for user fixtures
- Fast sandbox API for development/testing
- Paginated user retrieval (
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
XPEHO - GitHub Organization
- Spring Boot Documentation
- DummyJSON Users API Docs
- PostgreSQL Documentation
- Docker Documentation
- SonarQube Documentation
Made with ❤️ by XPEHO
⭐ If you found this helpful, please consider starring the repository!