go
30 lines · 7 steps
Validating URI params in a Gin handler
A Gin route binds and validates path parameters into a struct before touching the data store, then maps errors to precise HTTP status codes.
Explained by
highlit
1package handlers
2
3type BookURI struct {
4 Collection string `uri:"collection" binding:"required,alphanum"`
5 ID string `uri:"id" binding:"required,uuid"`
6}
7
8func GetBook(c *gin.Context) {
9 var params BookURI
10 if err := c.ShouldBindUri(¶ms); err != nil {
11 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
12 return
13 }
14
15 book, err := store.FindBook(c.Request.Context(), params.Collection, params.ID)
16 if errors.Is(err, ErrBookNotFound) {
17 c.JSON(http.StatusNotFound, gin.H{"error": "book not found"})
18 return
19 }
20 if err != nil {
21 c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to load book"})
22 return
23 }
24
25 c.JSON(http.StatusOK, book)
26}
27
28func RegisterBookRoutes(r *gin.Engine) {
29 r.GET("/collections/:collection/books/:id", GetBook)
30}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Struct tags let you declare validation rules once and enforce them at bind time instead of writing manual checks.
- 2Distinguishing a not-found error from a generic failure lets you return the right status code to the client.
- 3Validating and rejecting bad input before hitting the data store keeps invalid requests cheap and the store code clean.
Related explainers
go
package ratelimit import ( "context"
A token bucket rate limiter in Go
rate-limiting
concurrency
goroutines
Intermediate
7 steps
go
package cache import ( "context"
Cache-aside reads with singleflight in Go
caching
singleflight
concurrency
Advanced
8 steps
go
package httpx import ( "net/http"
A retrying HTTP transport in Go
http
middleware
retry
Intermediate
8 steps
go
package config import ( "fmt"
Loading typed config from environment variables in Go
configuration
environment-variables
type-parsing
Beginner
8 steps
go
package middleware import ( "crypto/subtle"
Building an API-key middleware in Gin
middleware
authentication
dependency-injection
Intermediate
5 steps
go
package api func RegisterRoutes(r *gin.Engine, deps *Dependencies) { r.GET("/health", func(c *gin.Context) {
Layering route groups and middleware in Gin
routing
middleware
authentication
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/validating-uri-params-in-a-gin-handler-explained-go-76ce/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.