Welcome to the final lesson of this unit! We’ve now built a powerful foundation for personalized AI tutoring, including prompt templates and multi-session management. In this last step, we'll expose our application’s tutoring capabilities through a REST API using Spring’s controller pattern. This will allow any client—web, mobile, or otherwise—to interact with our tutor in a structured and scalable way.
The TutoringController
class will serve as the bridge between your backend logic and any client—web, mobile, or otherwise—that wants to interact with your tutor. By the end of this lesson, you’ll have a flexible, production-ready controller for creating sessions, asking questions, and retrieving session data.
To keep our controller clean and expressive, we'll use record classes to define the shape of each request and response body. This approach provides both type safety and clear documentation for anyone consuming our API. By using records, we ensure that our data transfer objects are immutable and concise, making our code easier to maintain and understand.
These record classes will be used for serializing and deserializing JSON requests and responses for our session creation and question-answering endpoints. With these in place, we can now move on to setting up the controller itself.
The TutoringController
will be annotated with @RestController
, making it a web controller whose methods return data directly as JSON. All routes will be prefixed with /api/tutor
using @RequestMapping
. This structure helps organize our API endpoints and makes them easy to discover.
By injecting the StudentService
bean via the constructor, we delegate business logic and data management to a dedicated service layer. With our controller set up, let's look at how to create new tutoring sessions.
The /create
endpoint will let clients start a new tutoring session for a specific student and prompt template. It accepts a CreateSessionRequest
and returns a CreateSessionResponse
with the new session ID. This is the entry point for any new tutoring interaction.
This route expects a POST request with JSON like:
and responds with:
With session creation in place, we can now allow students to interact with the tutor by asking questions.
To interact with the tutor, clients will use the /ask
endpoint. It accepts an AskRequest
(student ID, session ID, and question) and returns the tutor’s answer in an AskResponse
. This endpoint is the core of the tutoring experience, enabling dynamic, session-based conversations.
Example request:
Example response:
After students have interacted with the tutor, it’s useful to be able to retrieve and manage their sessions. Let's see how to list all sessions for a student.
The /sessions/{studentId}
GET endpoint will list all session IDs for a given student. This is helpful for retrieving or managing previous tutoring sessions, allowing students or administrators to track progress over time.
Example response:
Now that we can list sessions, we may also want to review the full conversation history for a particular session. Let's add an endpoint for that.
The /history
endpoint will let clients fetch the full message history for a specific session. It requires the studentId
and sessionId
as query parameters. This feature is essential for reviewing past interactions, debugging, or providing context for ongoing tutoring.
This returns a list of Message
objects representing the conversation—including both user and tutor messages.
With all these endpoints in place, we have a robust API for managing and interacting with tutoring sessions!
In this final lesson, we built a clean, RESTful controller that connects our backend tutoring engine with any client application. We now have endpoints to create sessions, ask questions, list sessions, and fetch full conversation histories. This design empowers future integrations with web apps, mobile clients, or even other services.
In the practice section, we'll define and interact with these endpoints firsthand to solidify our understanding and see them in action.
