GinJuniorCoding
Как реализовать path parameters и query parameters в Gin?
Path-параметры извлекаются через c.Param(":name"), query-параметры — через c.Query("key") или c.DefaultQuery("key", "default"). Для автоматической конвертации типов и валидации используйте c.ShouldBindQuery(&struct{}).
Path parameters и query parameters в Gin
Gin позволяет извлекать параметры двух видов: из пути URL (path parameters) и из строки запроса (query parameters). Оба метода доступны через объект *gin.Context.
Path parameters
Параметры пути задаются в шаблоне маршрута через двоеточие (:param) или знак звёздочки (*param) для захвата остатка пути.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Обязательный параметр
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id") // строка
c.JSON(http.StatusOK, gin.H{"user_id": id})
})
// Wildcard: захватывает /files/a/b/c.txt -> path = "/a/b/c.txt"
r.GET("/files/*path", func(c *gin.Context) {
path := c.Param("path")
c.JSON(http.StatusOK, gin.H{"path": path})
})
r.Run(":8080")
}
Query parameters
Query параметры считываются через c.Query() (возвращает пустую строку если отсутствует) или c.DefaultQuery() (возвращает значение по умолчанию).
r.GET("/search", func(c *gin.Context) {
// GET /search?q=golang&page=2&active=true
q := c.Query("q") // "golang"
page := c.DefaultQuery("page", "1") // "2"
active := c.DefaultQuery("active", "false") // "true"
// Проверка наличия параметра
token, exists := c.GetQuery("token")
if !exists {
c.JSON(http.StatusBadRequest, gin.H{"error": "token required"})
return
}
c.JSON(http.StatusOK, gin.H{
"q": q,
"page": page,
"active": active,
"token": token,
})
})
Массивы и маппинг в query string
r.GET("/filter", func(c *gin.Context) {
// GET /filter?tags=go&tags=gin&tags=api
tags := c.QueryArray("tags") // []string{"go", "gin", "api"}
// GET /filter?ids[a]=1&ids[b]=2
ids := c.QueryMap("ids") // map[string]string{"a":"1", "b":"2"}
c.JSON(http.StatusOK, gin.H{"tags": tags, "ids": ids})
})
Конвертация типов через ShouldBindQuery
Вместо ручного парсинга строк удобнее использовать биндинг структуры:
type SearchQuery struct {
Q string `form:"q" binding:"required"`
Page int `form:"page" binding:"min=1"`
Limit int `form:"limit" binding:"min=1,max=100"`
Active bool `form:"active"`
}
r.GET("/search", func(c *gin.Context) {
var q SearchQuery
if err := c.ShouldBindQuery(&q); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, q)
})
Подводные камни
- c.Param() возвращает строку всегда. Нет автоматической конвертации в int или UUID — парсите вручную через
strconv.Atoiилиuuid.Parse. - Wildcard *param включает ведущий слеш.
/files/*pathпри запросе/files/doc.pdfвернёт/doc.pdf, а неdoc.pdf. - c.Query() не различает отсутствие и пустую строку. Используйте
c.GetQuery(), которая возвращает второй булев аргумент. - Конфликт маршрутов при смешении :param и статических сегментов.
/users/meи/users/:id— Gin выдаст panic при регистрации, если порядок неверный. - ShouldBindQuery не читает тело запроса. Для GET-параметров используйте
ShouldBindQuery, для тела POST —ShouldBindJSON. - URL-кодирование. Gin автоматически декодирует %XX в значениях, но если путь содержит закодированный слеш (%2F), он обрабатывается роутером до декодирования и маршрут может не совпасть.
Common mistakes
- Давать ответ про path и query parameters в Gin только на уровне определения, не показывая поведение в реальном приложении.
- Игнорировать границы ответственности вокруг темы «path и query parameters в Gin»: кто отменяет работу, кто владеет ресурсом и где формируется ответ клиенту.
- Не связывать path и query parameters в Gin с observability, тестированием или безопасностью, когда это влияет на продакшен-поведение.
What the interviewer is testing
- Точно объясняет, что именно делает path и query parameters в Gin и где это используется в Go-коде.
- Связывает path и query parameters в Gin с корректным lifecycle запроса, отменой, конкурентностью или конфигурацией сервера там, где это уместно.
- Не изобретает API и опирается на реальные контракты официальной документации.