A simple personalized learning platform for developers to track courses they want to learn. Built with Spring Boot and designed for beginners learning REST API development.
CodeCraftHub is a beginner-friendly REST API project that demonstrates how to build a complete CRUD (Create, Read, Update, Delete) application using Spring Boot. Instead of using a database, it stores data in a simple JSON file, making it easy to understand and debug.
CodeCraftHub/
├── pom.xml # Maven dependencies and build config
├── courses.json # Data storage (auto-created)
├── README.md # This documentation
└── src/main/java/com/codecrafthub/
├── CodeCraftHubApplication.java # Application entry point
├── model/
│ └── Course.java # Course data model
├── service/
│ └── CourseService.java # Business logic + file operations
├── controller/
│ └── CourseController.java # REST API endpoints
└── exception/
├── CourseNotFoundException.java # 404 error handling
├── InvalidCourseException.java # Validation error handling
├── FileOperationException.java # File I/O error handling
└── GlobalExceptionHandler.java # Central exception handler
- Full CRUD Operations - Create, read, update, and delete courses
- JSON File Storage - No database setup required
- Input Validation - Validates all required fields with helpful error messages
- Proper Error Handling - Returns appropriate HTTP status codes
- Auto-generated Fields - IDs and timestamps are created automatically
- Beginner-Friendly Code - Extensive comments throughout the codebase
- RESTful Design - Follows REST API best practices
Before you begin, ensure you have the following installed:
| Software | Version | Download Link |
|---|---|---|
| Java JDK | 17 or higher | Download Java |
| Maven | 3.6 or higher | Download Maven |
Open a terminal and run these commands to verify your setup:
# Check Java version
java -version
# Check Maven version
mvn -version# If using Git
git clone <repository-url>
cd CodeCraftHub
# Or simply navigate to the project folder
cd path/to/CodeCraftHub# Download all required dependencies
mvn clean installThis command will:
- Download Spring Boot and all dependencies
- Compile the Java source code
- Run any tests
- Package the application
# Option 1: Using Maven (recommended for development)
mvn spring-boot:run
# Option 2: Run the JAR file directly
java -jar target/codecrafthub-1.0.0.jarYou should see output similar to:
====================================
CodeCraftHub is running!
API Base URL: http://localhost:8080/api/courses
====================================
Open a new terminal and run:
curl http://localhost:8080/api/coursesYou should see a JSON array of courses.
Press Ctrl + C in the terminal where the server is running.
http://localhost:8080/api/courses
| Method | Endpoint | Description | Success Code |
|---|---|---|---|
POST |
/api/courses |
Create a new course | 201 Created |
GET |
/api/courses |
Get all courses | 200 OK |
GET |
/api/courses/{id} |
Get a course by ID | 200 OK |
PUT |
/api/courses/{id} |
Update a course | 200 OK |
DELETE |
/api/courses/{id} |
Delete a course | 204 No Content |
| Field | Type | Required | Description |
|---|---|---|---|
id |
number | Auto-generated | Unique identifier (starts from 1) |
name |
string | Yes | Name of the course |
description |
string | Yes | What the course covers |
target_date |
string | Yes | Target completion date (YYYY-MM-DD) |
status |
string | Yes | Must be: "Not Started", "In Progress", or "Completed" |
created_at |
string | Auto-generated | Timestamp when course was created |
Request:
curl -X POST http://localhost:8080/api/courses \
-H "Content-Type: application/json" \
-d '{
"name": "Spring Boot Fundamentals",
"description": "Learn to build REST APIs with Spring Boot",
"target_date": "2026-06-30",
"status": "Not Started"
}'Response (201 Created):
{
"id": 1,
"name": "Spring Boot Fundamentals",
"description": "Learn to build REST APIs with Spring Boot",
"target_date": "2026-06-30",
"status": "Not Started",
"created_at": "2026-05-05T10:30:00"
}Request:
curl http://localhost:8080/api/coursesResponse (200 OK):
[
{
"id": 1,
"name": "Spring Boot Fundamentals",
"description": "Learn to build REST APIs with Spring Boot",
"target_date": "2026-06-30",
"status": "In Progress",
"created_at": "2026-05-01T10:00:00"
},
{
"id": 2,
"name": "Docker for Developers",
"description": "Containerize your applications",
"target_date": "2026-08-01",
"status": "Not Started",
"created_at": "2026-05-03T14:45:00"
}
]Request:
curl http://localhost:8080/api/courses/1Response (200 OK):
{
"id": 1,
"name": "Spring Boot Fundamentals",
"description": "Learn to build REST APIs with Spring Boot",
"target_date": "2026-06-30",
"status": "In Progress",
"created_at": "2026-05-01T10:00:00"
}Response (404 Not Found) - If course doesn't exist:
{
"timestamp": "2026-05-05T10:30:00",
"status": 404,
"error": "Not Found",
"message": "Course not found with id: 99"
}Request:
curl -X PUT http://localhost:8080/api/courses/1 \
-H "Content-Type: application/json" \
-d '{
"name": "Spring Boot Fundamentals",
"description": "Updated: Master REST APIs with Spring Boot",
"target_date": "2026-07-15",
"status": "Completed"
}'Response (200 OK):
{
"id": 1,
"name": "Spring Boot Fundamentals",
"description": "Updated: Master REST APIs with Spring Boot",
"target_date": "2026-07-15",
"status": "Completed",
"created_at": "2026-05-01T10:00:00"
}Request:
curl -X DELETE http://localhost:8080/api/courses/1Response: 204 No Content (empty response body)
When required fields are missing or invalid:
{
"timestamp": "2026-05-05T10:30:00",
"status": 400,
"error": "Bad Request",
"message": "Validation failed",
"errors": [
"'name' is required",
"'status' must be one of: 'Not Started', 'In Progress', or 'Completed'"
]
}When the requested course doesn't exist:
{
"timestamp": "2026-05-05T10:30:00",
"status": 404,
"error": "Not Found",
"message": "Course not found with id: 99"
}When something goes wrong on the server:
{
"timestamp": "2026-05-05T10:30:00",
"status": 500,
"error": "Internal Server Error",
"message": "An error occurred while saving data. Please try again."
}Problem: Another application is using port 8080.
Solutions:
# Option A: Find and kill the process using port 8080
# On Windows:
netstat -ano | findstr :8080
taskkill /PID <PID_NUMBER> /F
# On Mac/Linux:
lsof -i :8080
kill -9 <PID_NUMBER>
# Option B: Change the port in application.properties
# Add this line: server.port=8081
# Then access API at http://localhost:8081/api/coursesProblem: Maven is not installed or not in your PATH.
Solutions:
- Download Maven from https://maven.apache.org/download.cgi
- Add Maven's
bindirectory to your system PATH - Restart your terminal after installation
Problem: Java is not installed or configured properly.
Solutions:
- Download Java 17+ from https://adoptium.net/
- Set JAVA_HOME environment variable to your JDK installation path
- Add
%JAVA_HOME%\bin(Windows) or$JAVA_HOME/bin(Mac/Linux) to PATH
Problem: Date is not in the correct format.
Solution: Use YYYY-MM-DD format:
{
"target_date": "2026-06-30"
}Problem: Status must be exactly one of the allowed values.
Solution: Use one of these exact strings (case-sensitive):
"Not Started""In Progress""Completed"
Check these:
-
Verify the URL is correct:
http://localhost:8080/api/courses -
Check if courses.json exists and is valid JSON:
- Open
courses.jsonin the project root - Ensure it's valid JSON (use a JSON validator)
- If corrupted, delete it and restart the app
- Open
-
Check the console for error messages:
- Look for stack traces or error logs
- Common issues: file permissions, disk space
Problem: The app caches data in memory.
Solution: Restart the application to reload data from the file.
If you encounter issues not covered here:
- Check the console output for error messages
- Verify your request format matches the examples above
- Ensure all required fields are provided
- Check that
courses.jsoncontains valid JSON
+------------------+------------------------+---------------------------+
| Action | Command | Expected Response |
+------------------+------------------------+---------------------------+
| Start server | mvn spring-boot:run | "CodeCraftHub is running" |
| List all | GET /api/courses | 200 + JSON array |
| Get one | GET /api/courses/1 | 200 + JSON object |
| Create | POST /api/courses | 201 + created course |
| Update | PUT /api/courses/1 | 200 + updated course |
| Delete | DELETE /api/courses/1 | 204 (no body) |
+------------------+------------------------+---------------------------+