Clients often want a list in a useful order: the cheapest products first, or names from A to Z. Go's slices.SortFunc sorts a slice. It can't compare two structs on its own, though, so you give it a compare function: a function that takes two items, a and b, and returns a negative number when a goes first, a positive one when b goes first, and 0 for a tie.
type Review struct {
User string
Stars int
}
func byStars(a, b Review) int {
return a.Stars - b.Stars
}
reviews := []Review{{"ana", 5}, {"bo", 3}}
slices.SortFunc(reviews, byStars)
// reviews is now [{bo 3} {ana 5}]
Write byStars without parentheses: you hand over the function itself, and SortFunc calls it on two items at a time. For text, strings.Compare(a, b) gives -1, 0 or 1 in alphabetical order. SortFunc sorts the slice you give it in place, so sort result, the fresh slice your handler builds, and the shop's products keep their order.
The client picks the order with a query parameter: ?sort=price or ?sort=name. Any other value is a mistake, so the shop answers 400 with an error. Without sort, the list keeps the shop's order, and the filters still work. The lists below show product names only; each item is a full product.
GET /products?sort=price → 200 [Pen, Notebook, Mug, Lamp]
GET /products?sort=name → 200 [Lamp, Mug, Notebook, Pen]
GET /products → 200 [Mug, Notebook, Lamp, Pen]
GET /products?category=office&sort=price → 200 [Pen, Notebook]
GET /products?sort=color → 400 {"error": "Sort must be price or name"}
Your task: write two compare functions, byPrice and byName. In the GET /products handler, read sort into sortBy, answer 400 for an unknown sort, and sort the filtered result by price or by name with slices.SortFunc.
Assignment
Follow the Coding Tutorial to add sorting to GET /products.
Hint
Sort after the filter loop, so only the products that passed the filters get sorted. Pass byPrice to slices.SortFunc without parentheses. The imports slices and strings are already there.
Free plan: 30 tutor messages. PRO is unlimited.
