A RESTful API for managing movies, categories, and user interactions built with Spring Boot. Users can browse movies, mark favorites, track watched films, and manage their personal movie lists.
A case study project for learning Java Spring Boot fundamentals.
- Secure authentication with JWT
- Role-based authorization (USER, ADMIN)
- Browse, search, and filter movies
- Add movies to favorites and mark as watched
- Category-based movie organization
- User profile management
- Admin panel for user and content management
- Pagination support for large datasets
- API documentation with Swagger/OpenAPI
- Docker and Docker Compose support
- Java 21
- Maven
- Spring Boot 3.5
- PostgreSQL
- Spring Security (JWT)
- Spring Data JPA (Hibernate)
- Swagger / OpenAPI
- Docker, Docker Compose
- Lombok
- MapStruct
- JUnit 5, Mockito, AssertJ (Testing)
- Java 21+
- Maven 3.9+
- PostgreSQL 15+
- Clone the repository:
git clone https://github.com/eneskaya12/cinecore.git
cd cinecore- Create a PostgreSQL database:
CREATE DATABASE cinecore;- Configure your database credentials in
src/main/resources/application.ymlor set environment variables:
export DATABASE_URL=jdbc:postgresql://localhost:5432/cinecore
export DATABASE_USERNAME=your_username
export DATABASE_PASSWORD=your_password- Run the application:
./mvnw spring-boot:run- Copy the environment template and configure:
cp .env.example .env
# Edit .env with your preferred settings- Start the application:
docker-compose up --build- Access the API:
http://localhost:8080
- Stop the containers:
docker-compose downThe application automatically seeds the database with sample data on first run:
Users:
| Password | Role | |
|---|---|---|
| admin@test.com | admin123 | ADMIN |
| user@test.com | user123 | USER |
Categories: Aksiyon, Komedi, Dram, Korku, Bilim Kurgu, Romantik
Movies:
| Title | Language | IMDB |
|---|---|---|
| Inception | EN | 8.8 |
| The Dark Knight | EN | 9.0 |
| Interstellar | EN | 8.6 |
| Kelebeğin Rüyası | TR | 8.0 |
| Ayla | TR | 8.3 |
| The Conjuring | EN | 7.5 |
Data is only seeded when the respective tables are empty.
Access Swagger UI to explore and test the API:
http://localhost:8080/swagger-ui.html
Handles user registration and login. Upon successful authentication, a JWT token is returned and must be included in the Authorization header for protected endpoints.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register a user |
| POST | /api/auth/login |
Login |
Allows authenticated users to manage their own profile.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users/profile |
Get own profile |
| PATCH | /api/users/profile |
Update own profile |
Administrative endpoints for managing users.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users |
Get all users |
| GET | /api/users/{id} |
Get user by ID |
| PATCH | /api/users/{id} |
Update user |
| DELETE | /api/users/{id} |
Delete user |
CRUD operations for movies. Public read access, admin-only write operations.
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/movies |
Get all movies | Public |
| GET | /api/movies/{id} |
Get movie by ID | Public |
| POST | /api/movies |
Add a new movie | Admin |
| PATCH | /api/movies/{id} |
Update a movie | Admin |
| DELETE | /api/movies/{id} |
Delete a movie | Admin |
CRUD operations for categories. Public read access, admin-only write operations.
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/categories |
Get all categories | Public |
| GET | /api/categories/{id} |
Get category by ID | Public |
| GET | /api/categories/{id}/movies |
Get movies in a category | Public |
| POST | /api/categories |
Add a new category | Admin |
| PATCH | /api/categories/{id} |
Update a category | Admin |
| DELETE | /api/categories/{id} |
Delete a category | Admin |
Manage associations between movies and categories.
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/movies/{movieId}/categories |
Get categories of a movie | Public |
| POST | /api/movies/{movieId}/categories/{categoryId} |
Add movie to category | Admin |
| DELETE | /api/movies/{movieId}/categories/{categoryId} |
Remove movie from category | Admin |
Allows users to track their movie interactions (favorites, watched).
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users/profile/movies |
Get all movies with status |
| GET | /api/users/profile/movies/favorites |
Get favorite movies |
| GET | /api/users/profile/movies/watched |
Get watched movies |
| GET | /api/users/profile/movies/{movieId}/status |
Get status of a movie |
| PUT | /api/users/profile/movies/{movieId}/status |
Update movie status |
The project includes comprehensive unit and integration tests.
./mvnw test| Type | Count | Description |
|---|---|---|
| Unit Tests | 50 | Service layer tests with mocked dependencies |
| Integration Tests | 59 | Controller tests with MockMvc |
| Total | 109 |
src/test/java/
├── config/
│ └── TestSecurityConfig.java # Security config for controller tests
├── controller/
│ ├── AuthControllerTest.java
│ ├── CategoryControllerTest.java
│ ├── MovieControllerTest.java
│ ├── MovieCategoryControllerTest.java
│ ├── MovieUserStatusControllerTest.java
│ ├── UserControllerTest.java
│ └── UserManagementControllerTest.java
└── service/impl/
├── AuthenticationServiceImplTest.java
├── CategoryServiceImplTest.java
├── MovieCategoryServiceImplTest.java
├── MovieServiceImplTest.java
├── MovieUserStatusServiceImplTest.java
└── UserServiceImplTest.java
# Run only unit tests
./mvnw test -Dtest="*ServiceImplTest"
# Run only integration tests
./mvnw test -Dtest="*ControllerTest"
# Run a specific test class
./mvnw test -Dtest=CategoryServiceImplTest| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection URL | jdbc:postgresql://localhost:5432/cinecore |
DATABASE_USERNAME |
Database username | cinecore |
DATABASE_PASSWORD |
Database password | - |
JWT_SECRET_KEY |
Secret key for JWT signing | - |
JWT_EXPIRATION |
Token expiration time (ms) | 3600000 (1 hour) |
