Start learning free

LESSON 33 OF 173 · BACKEND: YOUR FIRST API

Reviews for a Product in Go

Practice

Customers can now review a product: a number of stars from 1 to 5 and a short text. A review belongs to one product, so its path goes under the product's path: /products/1/reviews are the reviews of product 1. This is a nested path, and the ID in the middle is a path value, as in GET /products/1.

The reviews are already in the file, in the map reviews of type map[int][]Review: each key is a product ID, and each value is the slice of that product's reviews. A product with no reviews has no key, and reading a missing key gives the zero value, a nil slice. append works on a nil slice too. The same map of slices, with other values:

tags := map[int][]string{1: {"sale", "new"}}
fmt.Println(tags[1])   // [sale new]
fmt.Println(tags[2])   // []
tags[2] = append(tags[2], "gift")
fmt.Println(tags[2])   // [gift]

One path can have a route for each method. The GET route is already in your file: it answers a product's reviews, or [], and 404 when no product has the ID. You add POST on the same path: it adds the review at the end of the product's slice and answers 201 with it, or 404 when the product doesn't exist. Your code must answer these requests, in this order:

GET /products/1/reviews  →  200  [{"stars": 5, "text": "Great mug"}, {"stars": 4, "text": "A bit small"}]
GET /products/4/reviews  →  200  []
GET /products/99/reviews  →  404  {"error": "Product not found"}
POST /products/2/reviews  {"stars": 4, "text": "Nice paper"}  →  201  {"stars": 4, "text": "Nice paper"}
GET /products/2/reviews  →  200  [{"stars": 4, "text": "Nice paper"}]
POST /products/1/reviews  {"stars": 3, "text": "The handle gets hot"}  →  201  {"stars": 3, "text": "The handle gets hot"}
GET /products/1/reviews  →  200  [{"stars": 5, …}, {"stars": 4, …}, {"stars": 3, "text": "The handle gets hot"}]
POST /products/99/reviews  {"stars": 5, "text": "Love it"}  →  404  {"error": "Product not found"}
GET /products/1  →  200  {"id": 1, "name": "Mug", "price": 12, "category": "kitchen"}

Your task: below the GET /products/{id}/reviews route, add a route for POST /products/{id}/reviews. It reads the review from the body, finds the product, appends the review to reviews[id] and answers 201 with it; when no product has the ID, it answers 404 with "Product not found".


Assignment
Follow the Coding Tutorial to build the POST route on the nested path, next to the GET route that is already there.


Hint
Decode the body into a Review the way the PUT route decodes a product. Find the product with the loop and if of the GET route. append(reviews[id], review) works even when the product has no key yet: store the result back in reviews[id], and end the 201 answer with return.


STEP 1 OF 10
    Ctrl + Enter to check

    Shop Reviews in Go

    Keep going with Go1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free