Serving Your Personal Tutor with a RESTful API Using Sinatra

Welcome to the next step in our journey of building a personal tutor service with Sinatra, a lightweight Ruby web framework. In the previous lesson, we focused on the TutorController, which manages tutoring sessions and handles student queries by interacting with both the model and service layers. Now, we will take a significant step forward by creating a RESTful API for our personal tutor service using Sinatra. We'll start by setting up the main Sinatra application, then adapt the TutorController to integrate with Sinatra's session management.

Understanding RESTful APIs and Sinatra

RESTful APIs are a way for different software systems to communicate over the internet. They provide a set of rules that allow programs to exchange data using standard HTTP methods like GET, POST, and DELETE. Sinatra is a simple and flexible web framework for Ruby that makes it easy to build RESTful APIs. With Sinatra, you can quickly define routes, handle requests, and return responses, making it a great choice for building lightweight web services.

To get started with Sinatra, you can add it to your project by including it in your Gemfile:

Then run:

Or, you can install it directly:

Sinatra allows us to connect the components we've already built, enabling students to interact with our personal tutor service through a web interface or API endpoints.

Initializing a Sinatra App

First, we need to initialize the Sinatra application. Create a file called app.rb:

Here, we require Sinatra and related libraries, enable sessions, set a session secret, and configure the folders for static files and templates. We also create an instance of TutorController to manage tutoring operations.

Session Management in Sinatra

Sinatra provides built-in session management using cookies. By calling enable :sessions and setting a :session_secret, we ensure that session data is securely stored and signed. The session data is accessible via the session hash in your route handlers.

To uniquely identify each student and maintain continuity across requests, we can use Ruby's SecureRandom.uuid to generate a unique student ID and store it in the session. This is typically done using a helper method:

This helper checks if a :student_id exists in the session; if not, it generates a new UUID and stores it. This way, each student interacting with the service gets a unique identifier that persists across their session.

Setting Up Static Files and Templates

Sinatra makes it easy to serve static files and render templates. By default, static files are served from the public directory, and templates are rendered from the views directory.

Let's define the index route, which serves the main tutor interface using the erb method:

This route renders the tutor.erb template located in the views directory providing the user interface for the personal tutor service.

Creating New Tutoring Sessions

To create a new tutoring session, define a POST route:

This route uses the student_id helper to identify the student, calls the controller's create_session method, and returns the appropriate JSON response.

Handling Student Queries

To handle student queries, define another POST route. Sinatra does not have built-in request validation like some other frameworks, but you can manually validate incoming parameters in your route handlers. For JSON APIs, you can parse the request body and check for required fields:

This route parses the JSON request body, validates the required fields, and delegates the query to the controller.

Custom Exception Handling

Sinatra allows you to handle errors and return custom JSON responses. You can use the error block to catch exceptions and format error responses:

This ensures that unexpected errors and 404s return consistent JSON responses.

Running the Sinatra Server

To run your Sinatra application, simply execute:

By default, Sinatra will start a web server on http://localhost:4567. You can specify a different port by setting the PORT environment variable or by adding set :port, 3000 in your app.rb file:

This will make your application available at http://localhost:3000.

How Students Interact with the Personal Tutor API

To interact with our personal tutor service, a student can follow these steps:

  1. Access the Index Route (/): The student begins by accessing the index route of the API. This step ensures that a student session is established. A student session is a way to keep track of the student's interactions with the service. It is stored using Sinatra's session management, which utilizes cookies to maintain session data on the client side. The server responds with the tutor interface, ready for interaction.

  2. Create a Tutoring Session (/api/create_session): Before sending a query, the student needs to create a new tutoring session. This is done by sending a POST request to the /api/create_session route. The server will respond with a unique session ID, which is essential for identifying the tutoring session in subsequent interactions. The student session ensures that the tutoring session is associated with the correct student, allowing for personalized academic support.

  3. Send a Query (/api/send_query): With the tutoring session established, the student can now send academic questions to the personal tutor. This involves sending a POST request to the /api/send_query route, including the session ID and the query content in the JSON body. The server processes the query using the DeepSeek model and responds with the tutor's explanation, allowing the student to continue the learning conversation. The student session helps maintain continuity in the conversation by linking the queries to the correct student and tutoring session.

By following these steps, a student can effectively receive personalized academic support from our personal tutor service, leveraging the RESTful API to manage tutoring sessions and exchange queries while utilizing student sessions for a seamless learning experience.

Summary and Next Steps

In this lesson, we successfully built a RESTful API for our personal tutor service using Sinatra. We set up a Sinatra application, defined routes for tutoring operations, and explored how the TutorController integrates with Sinatra's session management. This lesson marks a significant milestone in our course, as it brings together all the components we've developed so far into a functional web application that can deliver personalized academic support at scale.

As you move on to the practice exercises, take the opportunity to experiment with the Sinatra API and reinforce the concepts covered in this lesson. This hands-on practice will prepare you for further development and exploration of additional Sinatra features and RESTful API concepts. Keep up the great work, and I look forward to seeing your progress!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal