This project is a learning-focused Spring Boot REST API that demonstrates the full backend development lifecycle:
- Designing REST resources
- Applying JPA & Hibernate ORM
- Modeling entity relationships
- Migrating from an in-memory database (H2) to PostgreSQL
- Running PostgreSQL in Docker with persistent volumes
The project evolves step-by-step across multiple branches to clearly show progress and decisions.
- Practice clean REST API design
- Understand JPA entity mapping and relationships
- Learn database migration (H2 → PostgreSQL)
- Learn Docker fundamentals for backend development
- Build something that can be reviewed, extended, and reused
├── topic
│ ├── Topic.java
│ ├── TopicRepository.java
│ ├── TopicService.java
│ └── TopicController.java
│
├── course
│ ├── Course.java
│ ├── CourseRepository.java
│ ├── CourseService.java
│ └── CourseController.java
│
├── lesson
│ ├── Lesson.java
│ ├── LessonRepository.java
│ ├── LessonService.java
│ └── LessonController.java
│
└── SpringbootApiApplication.java
The API models a simple learning platform: Topic → Course → Lesson
- Topic → Course : One-to-Many
- A topic can have many courses
- A course must belong to exactly one topic
- Course → Lesson : One-to-Many
- A course can have many lessons
- A lesson must belong to exactly one course
- Relationships are unidirectional
- Foreign keys are stored on:
course.topic_idlesson.course_id
This repository intentionally uses multiple branches to show incremental development.
- Basic Spring Boot REST API
- CRUD for:
- Topic
- hello
- updated it to use ResponseEntity
- Introduced JPA & Hibernate
- CRUD for:
- Course
- Lesson
- Added entity relationships:
- Topic → Course
- Course → Lesson
- Repository query methods:
findByTopicIdfindByCourseId
- H2 in-memory database
- Verified behavior with Postman
- Replaced H2 with PostgreSQL
- PostgreSQL runs in Docker
- Persistent storage via Docker volumes
- Spring Boot connects to PostgreSQL via JDBC
- Data persists across container restarts
This branch represents the current most complete version.
The project uses Docker only for the database while the Springboot application stills runs locally.
- Pulls official PostgreSQL image
- Exposes port
5432 - Uses a named volume for persistence
services:
postgres:
image: postgres:16
container_name: springboot-postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: springbootdb
POSTGRES_USER: springuser
POSTGRES_PASSWORD: springpass
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
inside application.properties (PostgreSQL):
spring.datasource.url=jdbc:postgresql://localhost:5432/springbootdb
spring.datasource.username=springuser
spring.datasource.password=springpass
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
##How to Run the Project (PostgreSQL Version)
1.Start Docker Engine
2.Navigate to project root
3.Run:
docker compose up
4.Run Spring Boot app from IntelliJ
5.API available at:
**http://localhost:8080**
##API Endpoints (Examples):
--> GET /topics
--> POST /topics
Courses:
--> POST /topics/{topicId}/courses
--> GET /topics/{topicId}/courses
Lessons:
--> POST /courses/{courseId}/lessons
--> GET /courses/{courseId}/lessons