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.
Before we dive in, let’s briefly recall two key concepts you’ll use in this lesson: Express routes and Prisma models.
- Express 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 withID1. - Prisma models are TypeScript classes (defined in your Prisma schema) that represent tables in your database. For example, you might have a
Recipemodel for recipes and anIngredientmodel for ingredients. These models make it easy to query and update your database using TypeScript code.
You’ll see both of these concepts in action as we build the recipe retrieval endpoints.
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.
In Express, you define a route using the router’s .get() method. Here’s how you set up a route to handle requests like /api/recipes/1:
- The
/:idpart means that this route will match any value in the URL and pass it to the function asreq.params.id. - The route only responds to
GETrequests because we are using.get().
Inside the route handler, you need to fetch the recipe from the database using its ID. You can do this with Prisma’s findUnique method:
- This code tries to find a recipe with the given
ID. If it doesn’t exist, we return a 404 error. - The
include: { ingredients: true }part fetches the related ingredients for the recipe.
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 using Prisma’s aggregate API:
- The
aggregatemethod calculates the average rating for the recipe. - If there are no ratings,
averageRatingwill benull.
Now, you need to return the recipe details as a JSON object. Here’s how you can do it:
- The
ingredientsfield is a list of ingredient names. - The
stepsfield contains the cooking instructions. - The
average_ratingfield shows the average rating ornullif there are no ratings.
Example Output:
This is what a user would see if they requested a specific recipe.
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.
You can set up a route for /api/recipes that accepts optional query parameters for pagination:
You can use the Zod library to validate and coerce query parameters. Zod helps ensure that incoming data is the correct type (for example, converting strings to numbers), provides default values, and gives consistent error messages if the input is invalid. This makes your endpoints more robust and user-friendly, and helps prevent bugs caused by unexpected input.
pagewill control which page we return. The code gets the page number from the URL, defaulting to 1.per_pagecontrols how many recipes to show per page, defaulting to 10.
Use Prisma’s findMany method with skip and take to get the right set of recipes, and count to get the total number of recipes:
skipdetermines how many recipes to skip based on the current page.takedetermines how many recipes to return per page.countgets the total number of recipes in the database.
Note that in this response, we will receive the ingredients as a list of integers, as this is the Primary Key of their table.
Now, build a JSON response that includes the recipes and pagination info:
In this lesson, you learned how to build two essential endpoints for your cooking helper app using Express and Prisma:
- 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 get comfortable with Express routes, Prisma queries, and formatting JSON responses — skills you’ll use throughout the rest of the course. Good luck, and have fun building your cooking helper!
