Skip to content

XPEHO/spring_boot_java_random_user

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Spring Boot Random User API

Java Spring Boot PostgreSQL License

A REST API built with Spring Boot that fetches users from DummyJSON Users API and stores them in PostgreSQL.

Quick Start β€’ API Docs β€’ Architecture


πŸ“¦ Prerequisites

  • Java 25+
  • Docker Desktop
  • Maven (wrapper included)

πŸš€ Quick Start

# 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:run

Access:


βš™οΈ Configuration

Environment Variables (.env)

POSTGRES_USER=your_user
POSTGRES_PASSWORD=your_password
POSTGRES_DB=your_database
POSTGRES_PORT=5432

External API Configuration

application.properties uses:

dummy.api.base-url=https://dummyjson.com/

Profiles

  • default: PostgreSQL (production)
  • local: Custom local settings
  • test: H2 in-memory database

πŸ“– API Documentation

Interactive Docs: http://localhost:8080/api
OpenAPI Spec: http://localhost:8080/v3/api-docs

Endpoints

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 βœ…

Example Request

# 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"
  }'

πŸ§ͺ Testing

# 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=CucumberIntegrationTest

Test Stack:

  • JUnit 5 - Testing framework
  • Mockito - Mocking
  • JaCoCo - Code coverage
  • Cucumber - BDD

πŸ—οΈ Architecture

Clean Architecture (3 Layers)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Presentation Layer              β”‚  ← REST Controllers
β”‚  (controllers, handlers)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Domain Layer                    β”‚  ← Business Logic
β”‚  (usecases, entities, exceptions)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Data Layer                      β”‚  ← Data Access
β”‚  (repositories, services, sources)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              ↓
         PostgreSQL

Domain Service Ports

  • LocalUserService: local persistence operations (save, read, delete) backed by PostgreSQL.
  • RemoteUserService: external user source contract used by use cases.

External Source Adapter

  • DummyUserApi: Retrofit client contract for DummyJSON endpoints.
  • DummyUserServiceImpl: adapter that calls DummyUserApi, maps DTOs, and returns PaginatedUsers.
  • RandomUserApi: Retrofit client contract for randomuser.me endpoints.
  • RandomUserServiceImpl: adapter that calls RandomUserApi, maps DTOs, and returns PaginatedUsers.

Project Structure

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

πŸ—„οΈ Database Schema

Users Table

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

Liquibase Migrations

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

πŸ“Š Monitoring

Actuator Endpoints

Available Metrics: JVM metrics, HTTP metrics, Database connection pool metrics


πŸ” Quality & CI/CD

SonarQube Analysis

./mvnw clean verify sonar:sonar

GitHub Actions

Workflow: .github/workflows/sonar.yaml

Triggers: Push to any branch, Pull requests

Pipeline:

  1. Sets up Java 25
  2. Runs Maven tests with code coverage
  3. Uploads results to SonarQube
  4. Waits for quality gate

Required Secrets:

  • SONAR_TOKEN - SonarQube authentication
  • SONAR_HOST_URL - SonarQube instance URL
  • POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_PORT

❌ Troubleshooting

DataSource Configuration Error

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.

PostgreSQL Connection Failed

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 localhost

Tests Fail with H2

Error:

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.Driver

Java Version Not Supported

Error:

error: release version 25 not supported

Solution:

  • Install Java 25 or later
  • Update Maven compiler plugin version in pom.xml

🌐 External API

This project integrates with DummyJSON Users API:


πŸ‘₯ Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘€ Author

XPEHO - GitHub Organization


πŸ”— Useful Links


Made with ❀️ by XPEHO

⭐ If you found this helpful, please consider starring the repository!

About

Projet Spring Boot Java avec l'API Random User

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors