Introduction: Making Recipe Search Smarter

Welcome back! In the last lesson, you learned how to build basic endpoints to retrieve recipes from your database, including fetching a single recipe by its ID and listing recipes with pagination. These are the building blocks of any recipe API.

Now, let’s take things a step further. Imagine you open a cooking app and want to find recipes that use only the ingredients you have in your kitchen. Or maybe you want to see the steps of a recipe as a list so you can follow them one by one. These features make your app much more helpful and user-friendly.

In this lesson, you’ll learn how to:

  • Search for recipes by a list of ingredients.
  • Return recipe steps as an array, not just a long string.

These skills will help you build a smarter, more flexible recipe API.

Quick Model Recap

Before we dive in, let’s quickly remind ourselves how our data is organized. This will help you understand how searching and filtering work.

With Prisma, your models are defined in the schema.prisma file. Here’s a simplified look at the relevant models:

  • The RecipeIngredient model acts as a join table, connecting recipes and ingredients in a many-to-many relationship.
  • Each Recipe can have many Ingredients, and each Ingredient can be used in many Recipes.
  • The steps field on Recipe is a string containing all the steps, separated by newlines.

This structure is important for searching recipes by ingredients.

Returning Recipe Steps as an Array

Many apps and websites want to show recipe steps one at a time, not as a single long string. To help with this, you can create an endpoint that returns the steps as an array.

Step 1: Fetching the Recipe

First, get the recipe by its ID using Prisma’s findUnique method. In Express, you can define a route like this:

  • findUnique will return null if the recipe does not exist, so you can check for that and return a 404 error.
Step 2: Splitting the Steps String

Assume the steps are stored as a string, with each step on a new line. You can split this string into an array:

  • .split(/\r?\n/) splits the steps string into an array wherever there is a line break. The regular expression /\r?\n/ matches both Unix (\n) and Windows (\r\n) line endings, so this works no matter which operating system was used to create the recipe. This ensures each step becomes a separate item in the array.
  • trim() removes any extra spaces.
  • The filter skips any empty lines.
Step 3: Returning the Steps as a List

To return the steps as an array, use Express’s res.json() method:

Example output:

This structure allows clients (like web or mobile apps) to easily loop through the steps and present them to users in a clear, step-by-step format.

Retrieving Recipes by Ingredients

Let’s say you want to find all recipes that use a specific set of ingredients, like "tomato" and "basil". You’ll need an endpoint that takes a list of ingredient names and returns only the recipes that use all of them.

Step 1: Accepting the Ingredient List

First, you need to accept a list of ingredient names from the user. In Express, you can do this by creating a POST endpoint that expects a JSON body:

  • req.body reads the JSON body from the request.
  • We check if the "ingredients" key is present and not empty.
  • We also convert all ingredient names to lowercase for case-insensitive matching.

Example input:

Step 2: Finding Matching Ingredient IDs

Next, you need to find the IDs of the ingredients that match the names provided. Here’s how you can find them using SQL:

  • This query selects all ingredient IDs where the name matches any of the provided names, case-insensitively.
  • If no ingredients are found, we return an empty list.
Step 3: Finding Recipes That Use All Ingredients

To find recipes that use all the specified ingredients, you can use another raw SQL query to count matches per recipe:

  • This query groups by recipeId and counts how many of the requested ingredients each recipe uses.
  • Only recipes where the count matches the number of requested ingredients are included.
Step 4: Returning the Results

Now, fetch the matching recipes and their ingredients, and return them as a JSON list:

Example output:

If no recipes match, you’ll get an empty list: [].

Review And What’s Next

In this lesson, you learned how to:

  • Return recipe steps as an array, making it easier for users to follow each step.
  • Search for recipes by a list of ingredients, returning only those that use all the specified ingredients.

These features make your recipe API much more useful and user-friendly. Up next, you’ll get to practice building and testing these endpoints yourself. This hands-on practice will help you solidify your understanding and prepare you for even more advanced features. Good luck!

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