Skip to content

Latest commit

Β 

History

History
615 lines (448 loc) Β· 15.2 KB

File metadata and controls

615 lines (448 loc) Β· 15.2 KB

Spring Boot Java Random User API

Java Spring Boot PostgreSQL License

A modern Spring Boot REST API that consumes the public Random User API and persists data in a PostgreSQL database. Includes interactive API documentation via Swagger UI / OpenAPI.

Features β€’ Quick Start β€’ API Endpoints β€’ Testing β€’ Architecture


πŸ“‹ Table of Contents

  1. Features
  2. Tech Stack
  3. Prerequisites
  4. Quick Start
  5. Configuration
  6. Running the Project
  7. API Documentation
  8. Testing
  9. Architecture
  10. Database Schema
  11. Monitoring
  12. Quality & CI/CD
  13. Troubleshooting
  14. Todo

✨ Features

  • βœ… RESTful API - Fetch and manage random users
  • βœ… PostgreSQL Integration - Persist data with Spring Data JDBC
  • βœ… OpenAPI/Swagger - Interactive API documentation at /api
  • βœ… Docker Support - Easy setup with Docker Compose
  • βœ… Health Monitoring - Spring Actuator endpoints
  • βœ… Code Quality - SonarQube integration via GitHub Actions
  • βœ… Test Coverage - JUnit 5 + Mockito + JaCoCo
  • βœ… BDD Testing - Cucumber support (in progress)
  • βœ… Environment Management - dotenv-java for secure configuration

πŸ› οΈ Tech Stack

Component Version Purpose
Java 25 Language
Spring Boot 4.0.3 Framework
Spring Web MVC (auto) REST API
Spring Data JDBC (auto) Database access
Spring Actuator (auto) Monitoring
PostgreSQL 15 Database
H2 (test) In-memory DB for tests
springdoc-openapi 3.0.1 OpenAPI/Swagger
dotenv-java 5.2.2 Environment config
Docker Compose - Local infrastructure
Maven Wrapper Build tool
JUnit 5 (auto) Testing framework
Mockito (auto) Mocking
JaCoCo 0.8.14 Code coverage

πŸ“¦ Prerequisites

  • Java 25+ (or compatible JDK)
  • Maven 3.8+ (included wrapper available)
  • Docker Desktop (for PostgreSQL)
  • Git (for version control)

πŸš€ Quick Start

1. Clone the repository

git clone https://github.com/XPEHO/spring_boot_java_random_user.git
cd spring_boot_java_random_user

2. Set up environment variables

cp .env.template .env
# Edit .env with your PostgreSQL credentials

3. Start PostgreSQL

docker-compose up -d

4. Run the application

./mvnw spring-boot:run

5. Access the API


βš™οΈ Configuration

Environment Setup

.env file (git-ignored)

cp .env.template .env

Content:

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

Local Profile (application-local.properties)

For local development with different credentials:

spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}

Set SPRING_PROFILES_ACTIVE=local in your IDE run configuration.

Test Profile (application-test.properties)

H2 in-memory database for unit tests (auto-configured, no setup needed).

Default Configuration

application.properties includes:

spring.application.name=spring_boot_java_random_user
spring.datasource.url=jdbc:postgresql://localhost:${POSTGRES_PORT}/${POSTGRES_DB}
spring.datasource.driver-class-name=org.postgresql.Driver
springdoc.swagger-ui.path=/api
randomuser.api.base-url=https://dummyjson.com/

πŸƒ Running the Project

Development Mode

# Using Maven wrapper (recommended)
./mvnw spring-boot:run

# Or with Maven installed
mvn spring-boot:run

Production Mode

# Build JAR
./mvnw clean package

# Run JAR
java -jar target/spring_boot_java_random_user-0.0.1-SNAPSHOT.jar

Docker Mode

# Build Docker image
docker build -t xpeho/spring-boot-random-user .

# Run container
docker run -p 8080:8080 --env-file .env xpeho/spring-boot-random-user

Application will be available at: http://localhost:8080


πŸ“– API Documentation

Interactive Swagger UI

http://localhost:8080/api

OpenAPI JSON Specification

http://localhost:8080/v3/api-docs

Available Endpoints

πŸ”΅ GET /random-users

Fetch and persist random users from the external API.

GET /random-users?count=500

Parameters:

  • count (optional): Number of users to fetch (default: 500, max: 5000)

Response: 200 OK

[
  {
    "id": 1,
    "gender": "male",
    "firstname": "John",
    "lastname": "Doe",
    "civility": "Mr",
    "email": "john.doe@example.com",
    "phone": "+1 234 567 8900",
    "picture": "https://example.com/pic.jpg",
    "nat": "US"
  }
]

🟒 GET /random-users/{id}

Retrieve a specific user by ID.

GET /random-users/1

Response: 200 OK or 404 Not Found

🟑 PUT /random-users/{id}

Update an existing user's information.

PUT /random-users/1
Content-Type: application/json

Request Body:

{
  "gender": "female",
  "firstname": "Jane",
  "lastname": "Smith",
  "civility": "Ms",
  "email": "jane.smith@example.com",
  "phone": "+1 987 654 3210",
  "picture": "pic.jpg",
  "nat": "FR"
}

Responses:

  • 200 OK - User updated successfully
  • 404 Not Found - User not found

πŸ§ͺ Testing

Run All Tests

./mvnw verify

Test execution lifecycle:

  1. pre-integration-test β†’ Docker Compose starts PostgreSQL
  2. integration-test β†’ Unit and integration tests run
  3. post-integration-test β†’ Docker Compose stops

Run Specific Test Suite

# Unit tests only
./mvnw test

# Integration tests only
./mvnw failsafe:integration-test

# Tests with specific tag (Cucumber)
./mvnw test -Dcucumber.filter.tags="@smoke"

Test Coverage Report

./mvnw clean verify

Generated reports:

  • HTML Report: target/site/jacoco/index.html
  • XML Report: target/site/jacoco/jacoco.xml (used by SonarQube)

Test Framework Details

  • Framework: JUnit 5
  • Mocking: Mockito
  • BDD: Cucumber (planned)
  • Coverage: JaCoCo

πŸ—οΈ Architecture

Project Structure

spring_boot_java_random_user/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main/
β”‚   β”‚   β”œβ”€β”€ java/com/xpeho/spring_boot_java_random_user/
β”‚   β”‚   β”‚   β”œβ”€β”€ SpringBootJavaRandomUserApplication.java    ← Entry point
β”‚   β”‚   β”‚   β”œβ”€β”€ config/                                      ← Spring configuration
β”‚   β”‚   β”‚   β”œβ”€β”€ data/                                        ← Data layer
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ converters/                              ← DTO/Entity conversion
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ models/                                  ← Data models
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ services/                                ← Data services
β”‚   β”‚   β”‚   β”‚   └── sources/                                 ← API & DB sources
β”‚   β”‚   β”‚   β”œβ”€β”€ domain/                                      ← Business logic
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ entities/                                ← Domain entities
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ exceptions/                              ← Custom exceptions
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ services/                                ← Business services
β”‚   β”‚   β”‚   β”‚   └── usecases/                                ← Use cases
β”‚   β”‚   β”‚   └── presentation/                                ← API layer
β”‚   β”‚   β”‚       β”œβ”€β”€ controllers/                             ← REST controllers
β”‚   β”‚   β”‚       └── handlers/                                ← Exception handlers
β”‚   β”‚   └── resources/
β”‚   β”‚       β”œβ”€β”€ application.properties                       ← Main config
β”‚   β”‚       β”œβ”€β”€ application-local.properties                 ← Local overrides
β”‚   β”‚       β”œβ”€β”€ schema.sql                                   ← DB schema
β”‚   β”‚       └── static/                                      ← Static assets
β”‚   └── test/
β”‚       β”œβ”€β”€ java/                                            ← Test code
β”‚       └── resources/
β”‚           β”œβ”€β”€ application-test.properties                  ← Test config
β”‚           └── features/                                    ← Cucumber features
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       β”œβ”€β”€ sonar.yaml                                       ← SonarQube CI/CD
β”‚       └── ISSUE_TEMPLATE/                                  ← GitHub templates
β”œβ”€β”€ docker-compose.yml                                       ← Local infrastructure
β”œβ”€β”€ pom.xml                                                  ← Maven config
β”œβ”€β”€ .env.template                                            ← Env variables template
β”œβ”€β”€ .gitignore                                               ← Git ignore rules
└── README.md                                                ← This file

Layered Architecture

Presentation Layer (Controllers)
         ↓
Domain Layer (Use Cases, Services)
         ↓
Data Layer (Repositories, Converters)
         ↓
Database (PostgreSQL)

πŸ—„οΈ Database Schema

Users Table

Column Type Constraints 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

DDL

Auto-generated on startup via schema.sql:

DROP TABLE IF EXISTS "users";

CREATE TABLE IF NOT EXISTS "users" (
    id SERIAL PRIMARY KEY,
    gender VARCHAR(20),
    firstname VARCHAR(100),
    lastname VARCHAR(100),
    civility VARCHAR(20),
    email VARCHAR(255),
    phone VARCHAR(50),
    picture VARCHAR(500),
    nationality VARCHAR(10)
);

πŸ“Š Monitoring

Health Check

http://localhost:8080/actuator/health

Actuator Endpoints

http://localhost:8080/actuator
http://localhost:8080/actuator/health
http://localhost:8080/actuator/metrics
http://localhost:8080/actuator/beans

Metrics

  • JVM metrics
  • HTTP metrics
  • Database connection pool metrics

πŸ” Quality & CI/CD

Local SonarQube Analysis

./mvnw clean verify sonar:sonar

GitHub Actions Workflows

🟦 SonarQube Analysis (.github/workflows/sonar.yaml)

Triggers:

  • Push to any branch
  • Pull requests

What it does:

  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 - DB user
  • POSTGRES_PASSWORD - DB password
  • POSTGRES_DB - DB name
  • POSTGRES_PORT - DB 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 Random User Generator API:


πŸ“ˆ Future Enhancements


βœ… Todo


πŸ‘₯ 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!