Leave Go syntax to skills/langs/go. ORM, logging libraries, and authentication schemes follow the project; do not specify them in this skill. Do not casually add full authentication middleware when the user has not called for it.
Do not write APIs from training data. First pin the 1.y version, then read the corresponding reference.
Pin the version
- Read
go.mod'srequire github.com/gin-gonic/gin(if there isreplace, replace takes precedence). Do not use a version that happens to be newer in the local module cache. - Take 1.y(
v1.12.0→1.12), open the file in the table below, and write code according to that file.
| 1.y | File |
|---|---|
| 1.10 | references/1.10.md |
| 1.11 | references/1.11.md |
| 1.12 | references/1.12.md |
For newer 1.y versions not listed: start from the highest covered tier, then check the official changelog / pkg.go.dev. For older versions: do not use the new APIs in this skill.
Routing and Middleware
- Use
Groupfor related paths, and mount common middleware on the group; do not copy it for every route. - Middleware is an onion:
c.Next()before is pre-processing, after is post-processing. What is registered first is on the outermost layer. gin.Default()=Logger+Recovery. In production, if you want fewer middleware,gin.New()then explicitlyUse。- Production:
GIN_MODE=releaseorgin.SetMode(gin.ReleaseMode)。 - When 405 is needed, set
engine.HandleMethodNotAllowed = true(by default, a wrong method on the same path is 404). - Path parameters are
:id, usec.Param("id"). Do not{id}。
Binding and Response
Prefer ShouldBind*, and write the error response yourself.Bind* will directly AbortWithError(400); if the project does not uniformly go through this, do not use it.
var req CreateUserReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, user)
- Fields must be exported; use
json/form/uri/header+bindingtag(go-playground/validator)。 - For JSON body use
ShouldBindJSON; for mixed query+form useShouldBind; for path parametersShouldBindUri。 - After writing the response,
return. Do notc.JSONa second time. - Struct responses are preferred over a screenful of
gin.H(except for debugging or when there is truly no fixed shape). c.Error(err)Leave it to the existing error middleware; if there is none, write the status code directly in the handler.
Context
gin.Context comes from sync.Pool, and will be reused after the request ends.
- Prohibitedto store
*gin.Contextin a struct / global / goroutine after the request ends. - To read a request snapshot in a goroutine:
cCopy := c.Copy(), use only the copy. - For downstream (DB, HTTP client) use
c.Request.Context(), and do not pass the gin Context down ascontext.Context. - Value retrieval: if there is already
GetString/GetIntetc., use it; do notc.MustGetand then blindly assert. ClientIP()depends on trusted proxies. Trusting all proxies by default is unsafe: if there is no reverse proxy,SetTrustedProxies(nil); if there is, fill in the proxy CIDR, or for a CDN useTrustedPlatform(gin.PlatformCloudflareetc.).