go 66 lines · 8 steps

Building a query URL from a Filter struct in Go

A Filter struct turns optional search criteria into a safely encoded URL query string.

Explained by highlit
1package search
2 
3import (
4 "net/url"
5 "strconv"
6 "strings"
7 "time"
8)
9 
10type Filter struct {
11 Query string
12 Categories []string
13 MinPrice float64
14 MaxPrice float64
15 InStock bool
16 UpdatedAt time.Time
17 Page int
18 PerPage int
19 SortBy string
20}
21 
22func (f Filter) URL(base string) (string, error) {
23 u, err := url.Parse(base)
24 if err != nil {
25 return "", err
26 }
27 
28 q := u.Query()
29 
30 if s := strings.TrimSpace(f.Query); s != "" {
31 q.Set("q", s)
32 }
33 for _, c := range f.Categories {
34 q.Add("category", c)
35 }
36 if f.MinPrice > 0 {
37 q.Set("price_min", strconv.FormatFloat(f.MinPrice, 'f', 2, 64))
38 }
39 if f.MaxPrice > 0 {
40 q.Set("price_max", strconv.FormatFloat(f.MaxPrice, 'f', 2, 64))
41 }
42 if f.InStock {
43 q.Set("in_stock", "true")
44 }
45 if !f.UpdatedAt.IsZero() {
46 q.Set("updated_since", f.UpdatedAt.UTC().Format(time.RFC3339))
47 }
48 
49 page := f.Page
50 if page < 1 {
51 page = 1
52 }
53 perPage := f.PerPage
54 if perPage < 1 || perPage > 100 {
55 perPage = 25
56 }
57 q.Set("page", strconv.Itoa(page))
58 q.Set("per_page", strconv.Itoa(perPage))
59 
60 if f.SortBy != "" {
61 q.Set("sort", f.SortBy)
62 }
63 
64 u.RawQuery = q.Encode()
65 return u.String(), nil
66}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Only setting query params for non-empty values keeps URLs clean and avoids sending meaningless defaults.
  2. 2Clamping pagination inputs to sane bounds protects downstream services from bad or hostile values.
  3. 3Using url.Values and Encode handles escaping for you, so never hand-concatenate query strings.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building a query URL from a Filter struct in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code