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")
publicclassExcuseController {
privatefinalExcuseServiceservice;
publicExcuseController(ExcuseServiceservice) {
this.service = service;
}
@GetMapping("/random")
publicList<Excuse> getRandom(@RequestParam(value="n", defaultValue="1") intn) {
returnservice.random(n);
}
@GetMapping("/{id}")
publicExcusegetById(@PathVariableLongid) {
returnservice.findById(id)
.orElseThrow(() -> newResponseStatusException(HttpStatus.NOT_FOUND, "Excuse not found"));
}
@GetMapping("/category/{cat}")
publicList<Excuse> getByCategory(@PathVariableStringcat) {
returnservice.findByCategory(cat);
}
}publicinterfaceExcuseRepositoryextendsJpaRepository<Excuse, Long> {
List<Excuse> findByCategory(Stringcategory);
}asyncfunctionfetchRandom(n=1){constresp=awaitfetch(`/api/excuses/random?n=${n}`);constdata=awaitresp.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.