Welcome back! So far, you’ve learned how to build API endpoints that let users retrieve recipes, search by ingredients, and view recipe steps. These features are essential for any recipe app, but sometimes users want a little more excitement or guidance. For example, what if someone can’t decide what to cook and wants a random suggestion? Or maybe they want to see the most popular recipes based on ratings from other users.
In this lesson, you’ll learn how to add two new features to your cooking helper API:
- An endpoint that returns a random recipe
- An endpoint that returns the most popular recipes based on user ratings
These features make your app more interactive and helpful, giving users new ways to discover recipes.
Before we dive in, let’s quickly remind ourselves how we’ve been working with recipes so far.
Previously, you built endpoints to:
- List all recipes with pagination (so users don’t get overwhelmed by too many results at once)
- Retrieve a single recipe by its ID
- Search for recipes by ingredients
All of these endpoints use Flask
for routing and SQLAlchemy
to interact with the database. You’ve also learned how to format JSON responses so that the data is easy to use in any app.
Now, let’s build on these skills to add dynamic selection features.
Let’s start by creating an endpoint that returns a random recipe. This is useful for users who want to try something new or can’t decide what to cook.
First, we need to define a new route in our Flask
app. We’ll use the @routes.route
decorator to create a GET endpoint at /api/recipes/random
.
This sets up the endpoint, but it doesn’t do anything yet.
To select a random recipe from the database, we use SQLAlchemy
’s order_by(func.random())
method. This tells the database to shuffle the recipes and pick the first one.
Recipe.query
starts a query for all recipes..order_by(func.random())
shuffles the order randomly..first()
picks the first recipe from the shuffled list.
If there are no recipes in the database, recipe
will be None
.
Now, let’s check if we found a recipe. If not, we return an error message. If we did, we return the recipe details as JSON.
- If no recipe is found, we return a 404 error.
- Otherwise, we build a JSON object with the recipe’s ID, name, list of ingredient names, and steps.
Here’s the complete function:
Example Output:
This endpoint gives users a fun way to discover new recipes with a single click.
Next, let’s create an endpoint that returns the most popular recipes. We’ll define “popular” as recipes with the highest average user ratings.
We’ll create a GET endpoint at /api/recipes/popular
.
To find popular recipes, we need to:
- Calculate the average rating for each recipe
- Sort recipes by their average rating, highest first
- Limit the results to the top 10 recipes
We can do this using SQLAlchemy
’s query features. First, we create a subquery that groups reviews by recipe and calculates the average rating.
Review.recipe_id
selects all recipe_ids that will be used in the grouping clause later in the code.func.avg(Review.rating)
calculates the average rating for each recipe..group_by(Review.recipe_id)
tells the database to group all the reviews that belong to the same recipe together. This way, when we calculate the average rating withfunc.avg(Review.rating)
, it computes the average for each recipe separately, not for all reviews combined. As a result, the query returns one row per recipe, with each row containing the recipe’s ID and its average rating.
Now, we join this subquery with the Recipe
table, sort by average rating, and limit it to 10 results.
.join(subquery, Recipe.id == subquery.c.recipe_id)
links each recipe to its average rating..order_by(subquery.c.avg_rating.desc())
sorts recipes from highest to lowest average rating..limit(10)
returns only the top 10 recipes.
Finally, we build a list of recipes with their details and average ratings.
- For each recipe, we include its ID, name, ingredients, steps, and average rating (rounded to two decimal places).
Here’s the complete function:
Example Output:
This endpoint helps users quickly find the best-rated recipes, making it easier to choose something delicious.
In this lesson, you learned how to add two new endpoints to your recipe API:
- One for serving a random recipe to help users discover new dishes
- One for listing the most popular recipes based on user ratings
These features make your app more dynamic and user-friendly. Now, you’re ready to practice building and using these endpoints in the exercises that follow. This will help you reinforce what you’ve learned and see how these features work in real scenarios.
Keep up the great work — your cooking helper app is becoming more powerful with each lesson!
