This repository was archived by the owner on Apr 4, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhttp_handlers.go
More file actions
90 lines (80 loc) · 2.43 KB
/
http_handlers.go
File metadata and controls
90 lines (80 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package main
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/gin-gonic/gin"
)
// Fetch a single int from URL query params by key
func intFromParams(params *url.Values, key string, defaultValue int) int {
if val := params.Get(key); val != "" {
if numericVal, err := strconv.Atoi(val); err == nil {
return numericVal
}
}
return defaultValue
}
// Ensures an int is between a min and max value
func constrainInt(num int, min int, max int) int {
if num < min {
return min
} else if max < num {
return max
} else {
return num
}
}
// Returns a link header string for pagination purposes
func getPageLinks(urlTemplate string, currentPage int, totalPages int) string {
linkTemplate := fmt.Sprintf("<%s>; rel=\"%s\"", urlTemplate, "%s")
pageUrls := make([]string, 0)
if totalPages == 1 {
// Single page - pagination not possible
return ""
}
if currentPage != 1 {
// Not first page
// Add link to previous page
pageUrls = append(pageUrls, fmt.Sprintf(linkTemplate, currentPage-1, "prev"))
}
if currentPage != totalPages {
// Not last page
// Add link to next page
pageUrls = append(pageUrls, fmt.Sprintf(linkTemplate, currentPage+1, "next"))
}
// Add link to last page
pageUrls = append(pageUrls, fmt.Sprintf(linkTemplate, totalPages, "last"))
// Add link to first page
pageUrls = append(pageUrls, fmt.Sprintf(linkTemplate, 1, "first"))
return strings.Join(pageUrls[:], ", ")
}
// Handles requests to the /search endpoint
func searchHandler(c *gin.Context) {
queryParams := c.Request.URL.Query()
searchTerm := queryParams.Get("query")
pageSize := 50
rawProducts := getProductIDs(searchTerm)
if len(rawProducts) == 0 {
c.JSON(http.StatusOK, rawProducts)
return
}
totalPages := len(rawProducts) / pageSize
if (len(rawProducts) % pageSize) > 0 {
totalPages++
}
currentPage := constrainInt(intFromParams(&queryParams, "page", 1), 1, totalPages)
urlTemplate := fmt.Sprintf("%s?query=%s&page=%s", c.FullPath(), searchTerm, "%d")
pageLinks := getPageLinks(urlTemplate, currentPage, totalPages)
if pageLinks != "" {
c.Writer.Header().Set("Link", pageLinks)
}
populatedProducts := make([]populatedProduct, 0)
for i := (currentPage - 1) * pageSize; i < len(rawProducts) && i < (currentPage*pageSize); i++ {
productMetadata := rawProducts[i]
fullProduct := getProductSpecs(productMetadata)
populatedProducts = append(populatedProducts, fullProduct)
}
c.JSON(http.StatusOK, populatedProducts)
}