Searching by name was one optional filter. A shop needs more: ?max_price=10, ?category=office, or several at once, joined with &. A request can send any mix of them, so no single fixed query fits: you build the query piece by piece.
Keep two slices side by side. conditions holds the pieces of the WHERE, each with a ?, and params, a []any, holds the values for those ?, in the same order. The visitor's text only ever goes into params, so the query stays safe. At the end, strings.Join glues the pieces with AND between them:
pieces := []string{"year >= ?", "author = ?"}
fmt.Println(strings.Join(pieces, " AND ")) // year >= ? AND author = ?
fmt.Println(strings.Join([]string{}, " AND ")) // an empty string
max_price is read with strconv.Atoi, which gives a number and an err. Test the filter with err == nil, not with maxPrice != 0: a maximum price of 0 is a real filter, and a missing max_price gives 0 too, with an error.
GET /products?max_price=10 → 200 [{"id": 2, "name": "Notebook", …}, {"id": 4, "name": "Pen", …}, {"id": 7, "name": "Stapler", …}]
GET /products?category=home → 200 [{"id": 3, "name": "Lamp", …}, {"id": 5, "name": "Plant", …}]
GET /products?category=office&max_price=8 → 200 [{"id": 2, "name": "Notebook", …}, {"id": 4, "name": "Pen", …}]
GET /products?name=Teapot&category=kitchen → 200 [{"id": 6, "name": "Teapot", "price": 22, "category": "kitchen", "stock": 4}]
GET /products?name=Lamp&max_price=20 → 200 []
GET /products?max_price=0 → 200 []
GET /products?category=x' OR '1'='1 → 200 []
GET /products → 200 [… all 8 products …]
Your task: next to name, let GET /products take the optional filters max_price (products costing at most that much) and category. Build the WHERE from the filters the request really sends, with a ? placeholder for each value.
Assignment
Follow the Coding Tutorial to check the filters, collect the conditions and their values, and run the query you built.
Hint
Add a condition and its value in the same if, so the two slices stay in step. Add " WHERE " only when len(conditions) > 0, and pass the values with params...: each one goes to its ?, in order.
Free plan: 30 tutor messages. PRO is unlimited.
