A production-ready REST API example built with Spring Boot 3.x and Java 17+, following the multi-module architecture pattern inspired by best practices.
example-rest-api/
├── pom.xml # Parent POM with dependency management
├── mvnw / mvnw.cmd # Maven Wrapper
├── .mvn/wrapper/ # Maven Wrapper files
├── .gitignore
│
├── api/ # REST API Layer
│ ├── pom.xml
│ ├── src/main/
│ │ ├── java/com/example/api/
│ │ │ ├── ApiApplication.java # Spring Boot entry point
│ │ │ ├── controller/ # REST Controllers
│ │ │ │ ├── PostController.java
│ │ │ │ └── UserController.java
│ │ │ ├── dto/ # Data Transfer Objects
│ │ │ │ ├── PostDto.java
│ │ │ │ ├── UserDto.java
│ │ │ │ ├── CommentDto.java
│ │ │ │ └── CreatePostRequest.java
│ │ │ └── exception/ # Exception handling
│ │ │ └── GlobalExceptionHandler.java
│ │ └── resources/
│ │ └── application.yml # Application configuration
│ └── src/test/ # Integration tests
│
├── service/ # Service Layer (Business Logic)
│ ├── pom.xml
│ └── src/main/java/com/example/
│ ├── service/
│ │ ├── PostService.java # Service interface
│ │ └── UserService.java
│ ├── service/impl/
│ │ ├── PostServiceImpl.java
│ │ └── UserServiceImpl.java
│ └── model/ # Domain models
│ ├── Post.java
│ ├── User.java
│ └── Comment.java
│
├── persistence/ # Persistence Layer (JPA)
│ ├── pom.xml
│ └── src/main/java/com/example/
│ ├── persistence/
│ │ ├── entity/ # JPA Entities
│ │ │ ├── PostEntity.java
│ │ │ └── UserEntity.java
│ │ └── repository/ # Spring Data Repositories
│ │ ├── PostRepository.java
│ │ └── UserRepository.java
│
└── integration/ # Integration Layer (External API)
├── pom.xml
└── src/main/java/com/example/
├── integration/
│ ├── client/ # HTTP Clients
│ │ ├── JsonPlaceholderClient.java
│ │ └── JsonPlaceholderClientImpl.java
│ ├── config/
│ │ └── WebClientConfig.java
│ └── mapper/
│ └── JsonPlaceholderMapper.java
This project follows a layered architecture with clear separation of concerns:
api ─────► service ─────► persistence
│
▼
integration
- api - REST controllers, DTOs, and Spring Boot application entry point
- service - Business logic, domain models, service interfaces and implementations
- persistence - JPA entities and Spring Data repositories (H2 in-memory database)
- integration - HTTP client for external APIs (JSONPlaceholder)
The project integrates with JSONPlaceholder - a free fake REST API for testing and prototyping.
- Java 17 or higher
- Maven 3.9+ (or use the included Maven Wrapper)
# Clone or navigate to the project directory
cd example-rest-api
# Build all modules
mvn clean install
# Or skip tests if you just want to compile
mvn clean install -DskipTests# From the api module directory
cd api
mvn spring-boot:runOr from the root directory:
mvn spring-boot:run -pl apiThe application will start on http://localhost:8080
# Run all tests
mvn test
# Run only integration tests in api module
cd apimvn test
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/posts |
Get all posts from local database |
| GET | /api/posts/{id} |
Get a post by ID |
| GET | /api/posts/user/{userId} |
Get posts by user ID |
| POST | /api/posts |
Create a new post |
| PUT | /api/posts/{id} |
Update a post |
| DELETE | /api/posts/{id} |
Delete a post |
| GET | /api/posts/external |
Get all posts from JSONPlaceholder |
| GET | /api/posts/external/{id} |
Get a post from JSONPlaceholder |
| GET | /api/posts/{id}/comments |
Get comments for a post |
| GET | /api/posts/external/{id}/comments |
Get comments from JSONPlaceholder |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users |
Get all users from local database |
| GET | /api/users/{id} |
Get a user by ID |
| GET | /api/users/external |
Get all users from JSONPlaceholder |
| GET | /api/users/external/{id} |
Get a user from JSONPlaceholder |
| Endpoint | Description |
|---|---|
/actuator/health |
Health check |
/actuator/info |
Application info |
curl http://localhost:8080/api/posts/externalResponse:
[
{
"id": 1,
"userId": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "..."
},
...
]curl http://localhost:8080/api/users/externalcurl -X POST http://localhost:8080/api/posts \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"title": "My New Post",
"body": "This is the body of my post"
}'curl http://localhost:8080/api/posts/external/1/commentsThe application uses an H2 in-memory database. Default configuration in api/src/main/resources/application.yml:
server:
port: 8080
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
h2:
console:
enabled: true
path: /h2-console
jpa:
hibernate:
ddl-auto: create-drop- The H2 console is available at
http://localhost:8080/h2-console - JDBC URL:
jdbc:h2:mem:testdb - No password required (empty)
- External API: JSONPlaceholder
- Spring Boot 3.3.5
- Java 17+
- Maven
- Spring Data JPA (with H2 database)
- Spring WebFlux (for WebClient)
- Lombok (for reducing boilerplate)
- MapStruct (for DTO mapping)
- H2 Database (in-memory)
- REST-assured (for testing)
This project is inspired by the jnie/multi-module-architecture repository.