Skip to main content

TP3.2 — Complete CRUD Application (Autonomous Mode)

Autonomous Challenge

This TP is exactly the same assignment as TP3.1, but without any provided code. You must do everything yourself. If you're stuck, refer to TP3.1 as a reference.

Estimated duration: 2h to 3h

Prerequisites: Understanding of Module 3 concepts (layered architecture, Spring Data JPA, REST API)


Context​

You are a backend developer in a school. You are asked to create a student management REST API with Spring Boot.


What you need to deliver​

Step 1 — Create the Spring Boot project​

  • Create a new Spring Boot project via Spring Initializr
  • Choose the necessary dependencies for:
    • Creating a REST API
    • Using an in-memory database (H2)
    • JPA persistence
    • Validating input data

Step 2 — Create the Student entity​

Create a Student entity with the following fields:

FieldTypeConstraints
idLongPrimary key, auto-generated
firstNameStringRequired, between 2 and 50 characters
lastNameStringRequired, between 2 and 50 characters
emailStringRequired, valid email format, unique
ageIntegerRequired, between 18 and 100
programStringRequired (e.g., "Computer Science", "Software Engineering")

Step 3 — Create the Repository​

  • Create a Repository interface for the Student entity
  • Add a method to check if an email already exists
  • Add a method to search students by program

Step 4 — Create the Service​

Create a Service that implements the following business logic:

  • Retrieve all students
  • Retrieve a student by ID — if the student does not exist, throw an appropriate exception
  • Create a student — check that the email is not already used before saving. If the email already exists, return a 409 (Conflict) error
  • Update a student — check that the student exists, then update their information
  • Delete a student — check that the student exists, then delete them

Step 5 — Create the REST Controller​

Create a Controller that exposes the following endpoints:

HTTP MethodURLActionExpected Return Code
GET/api/studentsList all students200 OK
GET/api/students/\{id\}Student details200 OK or 404 Not Found
POST/api/studentsCreate a student201 Created or 409 Conflict
PUT/api/students/\{id\}Update a student200 OK or 404 Not Found
DELETE/api/students/\{id\}Delete a student204 No Content or 404 Not Found
  • Data sent in POST and PUT must be automatically validated
  • If validation fails, return a 400 Bad Request code

Step 6 — Configure the H2 database​

  • Configure the application to use an in-memory H2 database
  • Enable the H2 console to view data in the browser
  • The console should be accessible at the URL /h2-console

Step 7 — Test all endpoints​

Test your API with Postman (or an equivalent tool). You must perform and capture the following tests:

  1. Create 3 students (POST) — check for code 201
  2. List all students (GET) — verify there are 3
  3. Retrieve a student by ID (GET) — verify the data
  4. Update a student (PUT) — change their program, verify the update
  5. Delete a student (DELETE) — check for code 204
  6. Relist all students — verify only 2 remain
  7. Test errors:
    • GET on a non-existent ID → 404
    • POST with an already used email → 409
    • POST with an invalid email → 400
    • POST with an empty first name → 400

Bonus exercises​

Bonus 1 — Search by program​

Add an endpoint to search students by program:

GET /api/students/program/{program}

For example: GET /api/students/program/Computer Science returns all students in Computer Science.


Bonus 2 — Statistics​

Add an endpoint that returns statistics:

GET /api/students/stats

The returned JSON should contain:

  • The total number of students
  • The average age
  • The number of students per program

Bonus 3 — Pagination​

Modify the GET /api/students endpoint to support pagination:

GET /api/students?page=0&size=10&sort=lastName

Bonus 4 — Centralized error handling​

Create a global exception handler that:

  • Returns clear error messages in JSON
  • Handles cases: student not found (404), duplicate email (409), validation failed (400)

Expected error response format:

{
"status": 404,
"message": "Student not found with ID: 99",
"timestamp": "2025-01-15T10:30:00"
}

Bonus 5 — Migration to PostgreSQL​

Replace H2 with PostgreSQL:

  • Create a studentdb database in PostgreSQL
  • Modify the configuration to point to PostgreSQL
  • Verify that data persists after restarting the application

Deliverables​

#DeliverableFormat
1Complete project source codeGit repository or ZIP
2Postman screenshots of the 10 tests (7 + 3 errors)Images
3Screenshot of the H2 console with dataImage
4At least 2 completed bonus exercisesCode
5Answers to the review questions (below)Text document

Review questions​

Answer these questions in your own words:

  1. What is the responsibility of each layer (Controller, Service, Repository)?
  2. Why do we separate code into distinct layers?
  3. What is the difference between @RestController and @Service?
  4. How does Spring Data JPA automatically generate SQL queries?
  5. What HTTP code should be returned after a successful creation? After a deletion?
  6. Why check the uniqueness of the email in the Service and not just in the database?
  7. What happens if an invalid JSON is sent to the Controller?
  8. What is the difference between findById() that returns an Optional and a method that directly returns the object?

Evaluation criteria​

CriterionPoints
Correctly implemented layered architecture (Controller → Service → Repository)20%
Student entity with all validations15%
Repository with custom methods10%
Service with complete business logic (checks, exceptions)20%
Controller with 5 functional CRUD endpoints20%
Successful Postman tests (normal cases + error cases)10%
Bonus exercises5%
Total100%

Advice

If you're stuck, don't spend more than 15 minutes on a problem. Check TP3.1 to see how it's done, then come back here and try to do it again without looking.


⬅️ TP3.1: CRUD Architecture (guided) | ⬅️ Back to Module 3