This is a Spring Boot application designed to demonstrate a layered architecture pattern in Java programming. The project uses a simple domain model to illustrate how responsibilities are separated across multiple layers to ensure loose coupling, maintainability, and scalability.
It was developed as a reference implementation of:
- Interlayer data flows
- DTO mapping
- Exception handling
- Application containerization with Docker
| Layer | Responsibility |
|---|---|
| Controller | Handles HTTP requests and responses |
| Service | Provides business logic |
| Repository | Handles database operations |
| Database | Persists structured data |
| Technology | Explanation |
|---|---|
| Java 8 | |
| Spring Boot | Application framework |
| Spring Web | REST API |
| Spring Data JPA | ORM & database interaction |
| Hibernate | JPA implementation |
| Redis | Cache |
| Postgre SQL | Database |
| Maven | Dependency management |
| Docker | Containerization |
- Designated data transfer format from the frontend
- Separates internal entity from API contract
- Global exception handler
- Custom exception format
- Standardized error response
-
Prerequisites
- JDK 1.8
- Maven 3.6.x or above
- Redis 8.6-alpine
- PostgreSQL 17
-
Build Project
mvn clean install
- Build Project and skip tests
mvn clean install -Dmaven.test.skip
-
Start Redis Service
-
Modify
src/main/resources/application.properties- Change
spring.redis.portto desired Redis port
- Change
-
For Windows systems
- Run on WSL
- Run Redis Docker image
-
-
Start Application
mvn spring-boot:run
- Run Unit Test
mvn test
Exposed port 8085
-
GET
/msgReturns a full list of messages
Sample Response
[ { "id": 0, "data": [ "object0", "object1", "object2" ], "info": "sample0" }, { "id": 1, "data": [ "object3", "object4" ], "info": "sample1" } ]Response Code
- 200 OK
- 500 Internal Server Error
-
GET
/msg/:idFetches a single message by ID
Sample Response
{ "id": 0, "data": [ "object0", "object1", "object2" ], "info": "sample0" }Response Code
- 200 OK
- 400 Bad Request
- 500 Internal Server Error
-
POST
/msgCreates a new message
Sample Request
{ "id": 0, "data": [ "object0", "object1", "object2" ], "info": "sample0" }Response Code
- 201 Created
- 500 Internal Server Error
-
PUT
/msg/:idUpdates provided fields of an existing message
Sample Request
{ "id": 0, "data": [ "object0", "object1", "object2", "object5" ], "info": "sample0-modified" }Sample Response
{ "id": 0, "data": [ "object0", "object1", "object2", "object5" ], "info": "sample0-modified" }Response Code
- 200 OK
- 400 Bad Request
- 500 Internal Server Error
-
DELETE
/msg/:idDelete an existing message
Response Code
- 200 OK
- 400 Bad Request
- 500 Internal Server Error
-
DELETE
/msgClears all messages
Response Code
- 200 OK
- 500 Internal Server Error
src/main/java/SpringbootDemo ├── controller │ └── MessageController ├── service │ ├── IMessageService │ └── MessageService ├── repository │ └── MessageRepo ├── entity │ ├── Message │ └── dto/MessageDto ├── config │ └── RedisCacheConfig ├── exception │ ├── MessageException │ ├── ErrorMessage │ ├── ErrorResponse │ └── GlobalExceptionHandler └── SpringbootDemoApplication
JPA Entity Configuration
@Table(name="tb_msg")
@Entity
class Message {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
long id;
@ElementCollection(targetClass = String.class, fetch = FetchType.EAGER)
@CollectionTable(name = "tb_data", joinColumns = @JoinColumn(name = "msg_id"))
@Column(nullable = false)
List<String> data;
@Column
String info;
}SQL Schema
CREATE TABLE tb_msg (
id INT NOT NULL AUTO_INCREMENT,
info VARCHAR(255),
PRIMARY KEY (id)
);
CREATE TABLE tb_data (
msg_id INT NOT NULL,
data VARCHAR(255) NOT NULL,
CONSTRAINT fk_msg
FOREIGN KEY (msg_id)
REFERENCES tb_msg(id)
ON DELETE CASCADE
);-
Build Docker Image
docker build -t spring-demo . -
Start Redis Container
docker run -p 9000:6379 redis:8.6-alpine -
Run App Container
docker run -p 8085:8085 spring-demo

