Welcome to Random-Excuse-API, a full-stack learning project built with Spring Boot (back-end), a lightweight front-end interface, and a simple embedded database. This project was crafted to help me deepen my understanding of Spring, REST design principles, and full-stack integration.
Hopefully, it'll make even a senior developer or recruiter say: “Oh wow, what an interesting project with a solid README!”
- Project Overview
- Architecture
- Getting Started
- API Endpoints & Usage
- Code Samples
- Screenshots
- What I Learned
- License
The Random-Excuse-API is a simple yet instructive full-stack application. It exposes RESTful endpoints where you can fetch excuses randomly, by specific category, or by ID. The front-end offers a UI to generate or filter excuses visually. Conceived explicitly as a sandbox for learning Spring Boot, I intentionally kept it lightweight and modular.
A three-tier structure:
- A simple file-based embedded H2 database containing an
excusestable. - Fields:
id,category,text. - Schema auto-created on app startup via Spring Data JPA.
- Exposes REST endpoints under
/api/excuses. - Built using Spring Boot with Spring MVC and Spring Data JPA.
- Exception handling with
@ControllerAdvicefor 404/400 cases. - Unit/integration testing via JUnit and MockMVC.
- Vanilla JavaScript + minimal HTML/CSS.
- Fetches from API and displays results dynamically.
- Select input for category, buttons to fetch random or custom amount.
- Java 11+
- Maven 3.6+
- Browser (Chrome/Firefox)
git clone https://github.com/PejperO/Random-Excuse-API.git
cd Random-Excuse-API
./mvnw spring-boot:run # Or: mvn clean package && java -jar target/*.jar- The API listens on
http://localhost:8080. - Front-end accessible via
http://localhost:8080/index.html.
Database and server ports can be configured in application.properties:
server.port=8080
spring.datasource.url=jdbc:h2:file:~/random-excuse-db
spring.jpa.hibernate.ddl-auto=updateGET /api/excuses/random
Response:
{
"id": 23,
"category": "office",
"text": "My coffee spilled on my keyboard and it started typing by itself."
}GET /api/excuses/{id}
Returns 404 if not found:
{ "error": "Excuse not found for id 101" }GET /api/excuses/category/{categoryName}
E.g., category/party
GET /api/excuses/random?n=5
Returns an array of n random excuses.
@RestController
@RequestMapping("/api/excuses")
public class ExcuseController {
private final ExcuseService service;
public ExcuseController(ExcuseService service) {
this.service = service;
}
@GetMapping("/random")
public List<Excuse> getRandom(@RequestParam(value="n", defaultValue="1") int n) {
return service.random(n);
}
@GetMapping("/{id}")
public Excuse getById(@PathVariable Long id) {
return service.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Excuse not found"));
}
@GetMapping("/category/{cat}")
public List<Excuse> getByCategory(@PathVariable String cat) {
return service.findByCategory(cat);
}
}public interface ExcuseRepository extends JpaRepository<Excuse, Long> {
List<Excuse> findByCategory(String category);
}async function fetchRandom(n=1) {
const resp = await fetch(`/api/excuses/random?n=${n}`);
const data = await resp.json();
displayExcuses(Array.isArray(data) ? data : [data]);
}
- 📦 Spring Boot auto-configuration & dependency injection
- 🗃️ Spring Data JPA and H2 database management
- 🌐 Designing clean RESTful APIs with error handling
- 💡 Asynchronous data fetching and UI updates with vanilla JS
- 📈 End-to-end testing with JUnit & MockMVC
- 🛡️ Deploying a full-stack sample with front & back properly integrated
This project is licensed under the MIT License. See the LICENSE file for details.