Introduction: The Role of Recipe Retrieval in Your App

Welcome to the first lesson of the Building the Recipe API course! In this lesson, you will learn how to build the core endpoints that allow your app to fetch recipes and their details from a database.

Recipe retrieval is a fundamental feature of any cooking helper app. Users need to be able to look up recipes, see what ingredients are required, and follow the steps to cook a dish. By the end of this lesson, you will know how to create endpoints that return a single recipe by its ID and a list of recipes with pagination. These skills are the foundation for more advanced features you’ll add later, such as searching, filtering, and user reviews.

Recall: API Routes and Database Models

Before we dive in, let’s briefly recall two key concepts you’ll use in this lesson: API routes and database models.

  • API routes are functions that respond to specific URLs in your web application. For example, when a user visits /api/recipes/1, a route function will handle that request and return the recipe with ID 1.
  • Database models are classes that represent tables in your database. For example, you might have a Recipe model for recipes and a Review model for user reviews. These models make it easy to query and update your database using Python code.

You’ll see both of these concepts in action as we build the recipe retrieval endpoints.

Building the Single Recipe Endpoint

Let’s start by building an endpoint that returns a single recipe by its ID. This is useful when a user wants to view the details of a specific recipe.

Step 1: Defining the Route

You define a route using a decorator. Here’s how you set up a route to handle requests like /api/recipes/1:

  • The {recipe_id} part means that this route will match any integer value in the URL and pass it to the function as recipe_id.
  • The response_model=RecipeDetail part ensures the response is formatted according to the RecipeDetail schema.
Step 2: Querying the Recipe

Inside the route function, you need to fetch the recipe from the database using its ID. You can do this by querying the database session:

  • This code tries to find a recipe with the given ID. If it doesn’t exist, an HTTP 404 error is raised.
Step 3: Calculating the Average Rating

Suppose your app allows users to rate recipes. You might want to show the average rating for each recipe. Here’s how you can calculate it:

  • func.avg(Review.rating) calculates the average rating for the recipe.
  • .filter(Review.recipe_id == recipe.id) ensures you only consider reviews for this recipe.
  • .scalar() gets the result as a single value.
  • If there are no ratings, average will be None.
Step 4: Building the JSON Response

Now, you need to return the recipe details as a response object. First, make sure you have a response class (Pydantic model) defined for the recipe details. For example:

Then, you can use this class to build and return the response:

  • The ingredients field is a list of ingredient names.
  • The steps field contains the cooking instructions.
  • The average_rating field shows the average rating or None if there are no ratings.

Example Output:

This is what a user would see if they requested a specific recipe.

Building the Paginated Recipes List Endpoint

Next, let’s build an endpoint that returns a list of recipes, but only a few at a time. This is called pagination, and it helps your app handle large numbers of recipes without overwhelming the user or the server.

Step 1: Defining the Paginated Route

You can set up a route for /api/recipes that accepts optional query parameters for pagination:

  • page will control which page we return, defaulting to 1.
  • per_page controls how many recipes to show per page, defaulting to 10.
Step 2: Querying and Paginating Recipes

Use the database session to get the right set of recipes:

  • total is the total number of recipes.
  • offset and limit are used to fetch only the recipes for the current page.
Step 3: Building the Paginated Response

Now, build a response object that includes the recipes and pagination info. First, define the response classes (Pydantic models) for the paginated recipes list. For example:

Then, you can use these classes to build and return the paginated response:

  • The recipes list contains the recipes for the current page.
  • The response also includes total (the total number of recipes), page (the current page), per_page (recipes per page), pages (total pages), and flags for has_next and has_prev.

Example Output:

Summary And What’s Next

In this lesson, you learned how to build two essential endpoints for your cooking helper app:

  • One to fetch a single recipe by its ID, including its ingredients and average rating.
  • Another to list all recipes with pagination, making it easy to browse through many recipes.

These endpoints are the backbone of your app’s recipe retrieval features. In the practice exercises that follow, you’ll get hands-on experience implementing and testing these endpoints yourself. This will help you become comfortable with defining API routes, querying your database, and formatting response objects — skills you’ll use throughout the rest of the course. Good luck, and have fun building your cooking helper!

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