sakila/internal/httpapi/categories.go

104 lines
2.9 KiB
Go
Raw Normal View History

package httpapi
import (
"database/sql"
"net/url"
"strconv"
"strings"
hres "form-builder-be-go/internal/hal"
sq "form-builder-be-go/internal/sqlc"
"github.com/gin-gonic/gin"
"github.com/raff/halgo"
)
func RegisterCategoryRoutes(r *gin.Engine, db *sql.DB) {
// List categories
r.GET("/categories", func(c *gin.Context) {
limit := parseIntDefault(c.Query("limit"), 20)
if limit > 100 {
limit = 100
}
offset := parseIntDefault(c.Query("offset"), 0)
order := c.Query("order") // currently static ORDER BY in query; keep for link preservation
q := sq.New(db)
cats, err := q.ListCategories(c, sq.ListCategoriesParams{Limit: int64(limit), Offset: int64(offset)})
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
total, err := q.CountCategories(c)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
selfURL := buildURL("/categories", limit, offset, order, c.Query("expand"))
res := hres.New(selfURL)
res.AddCurie()
res.AddLink("self", halgo.Link{Href: selfURL})
if int64(offset+limit) < total {
nextURL := buildURL("/categories", limit, offset+limit, order, c.Query("expand"))
res.AddLink("next", halgo.Link{Href: nextURL})
}
if offset > 0 {
prev := offset - limit
if prev < 0 {
prev = 0
}
prevURL := buildURL("/categories", limit, prev, order, c.Query("expand"))
res.AddLink("prev", halgo.Link{Href: prevURL})
}
var embedded []interface{}
for _, cat := range cats {
itemURL := "/categories/" + strconv.FormatInt(cat.CategoryID, 10)
item := hres.New(itemURL)
item.SetState(cat)
item.AddLink("self", halgo.Link{Href: itemURL})
name := strings.TrimSpace(cat.Name)
if name != "" {
qv := url.Values{"category.name": []string{name}}
item.AddLink("sakila:films", halgo.Link{Href: "/films?" + qv.Encode()})
}
embedded = append(embedded, item)
}
res.Embed("categories", embedded)
res.SetState(gin.H{"count": len(cats), "total": total, "limit": limit, "offset": offset})
c.Header("Content-Type", "application/hal+json")
c.JSON(200, res)
})
// Get category
r.GET("/categories/:id", func(c *gin.Context) {
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "invalid id"})
return
}
q := sq.New(db)
cat, err := q.GetCategory(c, id)
if err != nil {
if err == sql.ErrNoRows {
c.JSON(404, gin.H{"error": "not found"})
return
}
c.JSON(500, gin.H{"error": err.Error()})
return
}
self := "/categories/" + strconv.FormatInt(cat.CategoryID, 10)
res := hres.New(self)
res.AddCurie()
res.SetState(cat)
res.AddLink("self", halgo.Link{Href: self})
name := strings.TrimSpace(cat.Name)
if name != "" {
qv := url.Values{"category.name": []string{name}}
res.AddLink("sakila:films", halgo.Link{Href: "/films?" + qv.Encode()})
}
c.Header("Content-Type", "application/hal+json")
c.JSON(200, res)
})
}