Skip to content

nurmanhadi/webtoon-java-springboot-with-cloud-storage-cloudinary

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

64 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“š Webtoon RESTful API

A comprehensive RESTful API for managing webtoons, allowing users to handle comics, chapters, and content (images) easily. Built with Spring Boot and Java 21, the application includes secure authentication with JWT, file uploads to Cloudinary, and robust input validation.


πŸš€ Features

  • πŸ” JWT Authentication
  • πŸ“š CRUD Operations for Comics
  • πŸ“– CRUD Operations for Chapters
  • πŸ–ΌοΈ CRUD Operations for Content (Image Pages)
  • ☁️ Upload Images to Cloudinary
  • πŸ“Š Pagination and Sorting
  • πŸ›‘οΈ Input Validation
  • πŸ“¦ Consistent JSON Response Wrapper
  • πŸ«™ Dockerfile and Docker Compose
  • 🌏 Ready Production

πŸ› οΈ Tech Stack

  • Java 21
  • Spring Boot
  • MySQL
  • Cloudinary
  • Lombok
  • Jakarta Bean Validation

πŸ“‹ Requirements

  • Java 21
  • Maven 3+
  • MySQL 8+
  • Cloudinary Account

βš™οΈ Setup & Run the Project

1. Clone the Repository

git clone https://github.com/nurmanhadi/webtoon-java-springboot-with-cloud-storage-cloudinary.git
cd webtoon-java-springboot-with-cloud-storage-cloudinary

2. Configure application.properties

Edit the file at src/main/resources/application.properties:

spring.threads.virtual.enabled=true

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/your-database
spring.datasource.username=your-username
spring.datasource.password=your-password

spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=30

cloudinary.cloud-name=your-cloud-name
cloudinary.api-key=your-api-key
cloudinary.api-secret=your-api-secret

3. Setup Database

Create the required tables using the schema provided in the database/ folder.

4. Run the Application

./mvnw spring-boot:run

πŸ“– API Documentation

User Path Header Required
Admin api/admin Authorization: Bearer JWT βœ…
Anonim api/public None ❌

πŸ‘€ User & Auth

Register

POST /api/auth/register

{
  "username": "your_username",
  "password": "your_password"
}

Login

POST /api/auth/login

{
  "username": "your_username",
  "password": "your_password"
}

πŸ“˜ Comic Endpoints

Create Comic

POST /api/admin/comics

Form Data:

Key Type Required
cover file βœ…
title text βœ…
synopsis text βœ…
author text βœ…
artist text βœ…
type text βœ…

Update Comic

PUT /api/admin/comics/{comicId}

Get All Comics

GET /api/public/comics?page=1&size=10

Get Comic by ID

GET /api/public/comics/{comicId}

Search Comic

GET /api/public/comics/search?keyword={keyword}&page={page}&size={size}

Get ALl Comic By Type

GET /api/public/comics/type?type={type}&page={page}&size={size}

Delete Comic

DELETE /api/admin/comics/{comicId}


πŸ“– Chapter Endpoints

Create Chapter

POST /api/admin/comics/{comicId}/chapters

{
  "number": 1
}

Update Chapter

PUT /api/admin/comics/{comicId}/chapters/{chapterId}

{
  "number": 2
}

Get All Chapters

GET /api/public/comics/{comicId}/chapters

Get Chapter by ID

GET /api/public/comics/{comicId}/chapters/{chapterId}

Delete Chapter

DELETE /api/admin/comics/{comicId}/chapters/{chapterId}


πŸ–ΌοΈ Content Endpoints

Upload Content Image

POST /api/admin/comics/{comicId}/chapters/{chapterId}/contents
Form Data:

Key Type Required
content file βœ…

Update Content

PUT /api/admin/comics/{comicId}/chapters/{chapterId}/contents/{contentId}

Get All Content by Chapter Number

GET /api/public/comics/{comicId}/chapters/{chapterNumber}/contents

Delete Content

DELETE /api/admin/comics/{comicId}/chapters/{chapterId}/contents/{contentId}


πŸ“– Category Enpoints

Add Category

POST /api/admin/categories

{
  "name": "harem"
}

Update Category

PUT /api/admin/categories/{categoryId}

{
  "name": "action"
}

Get All Category

GET /api/public/categories


πŸ“– Comic Category Enpoints

Add Comic Category

POST /api/admin/comic-categories

{
  "comicId": 7,
  "categoryId": 3
}

Get all by Category Id

GET /api/admin/comic-categories/categories/{categoryId}?page={page}&size={size}

Delete Comic Category

DELETE /api/admin/comic-categories/{comicCategoryId}


βœ… Success Response Format

{
  "data": "OK",
  "error": null
}

❌ Error Response Format

{
  "data": null,
  "error": "resource not found"
}

πŸ“Œ Notes

  • All /api/admin/** endpoints require a valid JWT token.
  • File uploads are stored in Cloudinary and accessible via returned URLs.
  • Spring's validation handles input validation via Jakarta Bean Validation.
  • The project uses consistent response wrapping to standardize API output.

πŸ“ License

This project is licensed under the Apache License 2.0. You are free to use, modify, and distribute this project under the terms of that license.


About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages