A client often wants only part of the data, and it can say so in the URL. Everything after the ? is the query string, made of name=value pairs. In /products?max_price=10 the path is still /products, so the same handler answers: max_price is the name and 10 is the value.
In Go you read a query parameter with r.URL.Query().Get("max_price"). Everything in a URL is text, and a missing parameter gives the empty text "". strconv.Atoi turns text into a whole number. It gives back two values, the number and an error: the error is nil when the text was a whole number, and not nil when it is empty or a word (then the number is 0). Here is the idea on another route:
app.HandleFunc("GET /double", func(w http.ResponseWriter, r *http.Request) {
number, err := strconv.Atoi(r.URL.Query().Get("number"))
if err != nil {
fmt.Fprint(w, "Send a whole number, like /double?number=4")
return
}
fmt.Fprint(w, number*2)
})
The filter is a loop you already know: start an empty slice, go through the products, and append the ones that pass the check. When there is no usable max_price, err is not nil and every product passes, so /products still answers the whole list. Your code must give:
GET /products?max_price=10 → 200 [{"id": 2, "name": "Notebook", …}, {"id": 4, "name": "Pen", …}]
GET /products?max_price=12 → 200 [{"id": 1, "name": "Mug", …}, {"id": 2, …}, {"id": 4, …}]
GET /products?max_price=1 → 200 []
GET /products → 200 all 4 products
GET /products?max_price=cheap → 200 all 4 products
GET /products/3 → 200 {"id": 3, "name": "Lamp", "price": 29, "category": "home"}
Your task: fill in the "GET /products" handler so it reads max_price from the query string and answers only the products that cost maxPrice or less, or every product when there is no limit.
Assignment
Follow the Coding Tutorial to read max_price and filter the products in the "GET /products" handler.
Hint
Check err != nil first, then ||, then compare the price with <=. Call writeJSON after the loop, not inside it.
Free plan: 30 tutor messages. PRO is unlimited.
