Ingredients and Reviews Endpoints
Introduction: Enhancing Our Cooking API
Welcome back! In the last lesson, you learned how to make your cooking assistant more accessible by generating audio instructions using the gTTS library. Now, we are going to make your API even more useful and interactive by adding two new features: the ability to list all available ingredients and to let users submit reviews for recipes.
These features are important for any smart cooking app. Listing ingredients helps users see what’s available or filter recipes, while reviews allow users to share feedback and help others find the best recipes. By the end of this lesson, you will know how to build and test these endpoints in Flask.
Quick Recall: Flask Endpoints Refresher
Before we dive in, let’s quickly remind ourselves how Flask endpoints work. In Flask, an endpoint is a function that runs when a user visits a certain URL. You define endpoints using the @app.route decorator, and you can specify which HTTP methods (like GET or POST) the endpoint should accept.
For example, here’s a simple GET endpoint:
- The
@app.route('/hello', methods=['GET'])line tells Flask to run thesay_hellofunction when someone visits/hellousing theGETmethod. - The function returns a JSON response.
In this lesson, you’ll use similar patterns to build your new endpoints.
Building the Ingredients Endpoint
Let’s start by creating an endpoint that lists all unique ingredients in your database. This will be a GET endpoint, which means users will request data from it.
Step 1: Define the Route
First, you need to define a new route for your endpoint. In your Flask app, you can use a blueprint or the main app object. Here’s how you define the route using a blueprint:
@routes.route('/api/ingredients', methods=['GET'])sets up the endpoint at/api/ingredientsand only allowsGETrequests.
Step 2: Query the Database
Next, you want to get all unique ingredient names from the database. You can use SQLAlchemy to do this:
db.session.query(Ingredient.name)asks the database for all ingredient names..distinct()ensures you only get each name once, even if it appears in multiple recipes..all()returns all results as a list of tuples.
Step 3: Format the Results
The result from the database will look like this: [('egg',), ('flour',), ('milk',)]. You want to return a simple list of strings. You can do this with a list comprehension:
[name[0] for name in ingredient_names]extracts the string from each tuple.jsonify(...)turns the list into a JSON response., 200sets the HTTP status code to 200 (OK).
Full Example
Here’s the complete endpoint:
Example Output:
If your database has eggs, flour, and milk, a GET request to /api/ingredients will return:
This endpoint is now ready to help users see all available ingredients.
Building the Reviews Endpoint
Now, let’s add a way for users to submit reviews for recipes. This will be a POST endpoint, which means users will send data to it.
Step 1: Define the Route
Set up the route for submitting reviews:
- This endpoint will accept
POSTrequests at/api/reviews.
Step 2: Get and Validate the Data
You need to get the data the user sends and make sure it’s valid. The user should send a recipe_id and a rating (between 1 and 5).
request.get_json()gets the data sent in the request.data.get('recipe_id')anddata.get('rating')extract the values.- The
ifstatement checks that both values are present and that the rating is between 1 and 5. - If the data is invalid, the function returns an error message and a 400 (Bad Request) status.
Step 3: Save the Review
If the data is valid, you can create a new review and save it to the database:
Review(recipe_id=recipe_id, rating=rating)creates a new review object.db.session.add(review)adds it to the database session.db.session.commit()saves it to the database.
Step 4: Return a Confirmation
Finally, return a message to let the user know the review was saved:
- The message confirms the review was saved.
- The status code 201 means “Created.”
Full Example
Here’s the complete endpoint:
Example Input:
A user might send this JSON to /api/reviews:
Example Output:
If the input is invalid, for example, if the rating is 6:
The output will be:
Summary and Practice Preview
In this lesson, you learned how to add two important features to your smart cooking API: listing all unique ingredients and allowing users to submit reviews for recipes. You saw how to define new endpoints, query the database, validate user input, and return clear JSON responses.
Next, you’ll get a chance to practice what you’ve learned. The upcoming exercises will help you reinforce these skills by guiding you through building and testing similar endpoints on your own. This hands-on practice will ensure you’re comfortable working with Flask routes, database queries, and handling user data. Good luck!
