Gin Cheat Sheet
Complete reference guide for Gin with interactive examples and live playground links
Click on any section to jump directly to it
Basic Setup
Basic Setup
Basic Gin server setup with a simple route
Gin
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
// Create a default gin router
r := gin.Default()
// Define a route
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
// Run the server
r.Run(":8080")
}
Project Structure
Recommended project structure for Gin applications
Gin
project/
├── main.go
├── config/
│ └── config.go
├── controllers/
│ └── user_controller.go
├── models/
│ └── user.go
├── routes/
│ └── routes.go
├── middleware/
│ └── auth.go
└── utils/
└── helpers.go
Routing
Route Groups and Middleware
Route grouping and middleware usage
Gin
func main() {
r := gin.Default()
// Middleware
r.Use(gin.Logger())
r.Use(gin.Recovery())
// Route groups
api := r.Group("/api")
{
v1 := api.Group("/v1")
{
v1.GET("/users", getUsers)
v1.POST("/users", createUser)
}
v2 := api.Group("/v2")
{
v2.GET("/users", getUsersV2)
}
}
// Group-specific middleware
authorized := r.Group("/")
authorized.Use(AuthRequired())
{
authorized.POST("/login", loginEndpoint)
authorized.POST("/submit", submitEndpoint)
}
}
Request Methods
Different HTTP methods in Gin
Gin
func main() {
r := gin.Default()
// GET request
r.GET("/users", getUsers)
// POST request
r.POST("/users", createUser)
// PUT request
r.PUT("/users/:id", updateUser)
// DELETE request
r.DELETE("/users/:id", deleteUser)
// PATCH request
r.PATCH("/users/:id", patchUser)
// Any method
r.Any("/any", handleAny)
// Multiple methods
r.Handle("GET", "/handle", handleGet)
r.Handle("POST", "/handle", handlePost)
}
Request Handling
Request Parameters
Handling different types of requests and parameters
Gin
// Path parameters
r.GET("/user/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{"id": id})
})
// Query parameters
r.GET("/search", func(c *gin.Context) {
query := c.DefaultQuery("q", "default")
page := c.DefaultQuery("page", "1")
c.JSON(http.StatusOK, gin.H{
"query": query,
"page": page,
})
})
// Form data
r.POST("/form", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
})
})
// JSON binding
type User struct {
Name string `json:"name"`
Email string `json:"email"`
Password string `json:"password"`
}
r.POST("/users", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, user)
})
File Upload
File upload handling in Gin
Gin
// Single file upload
r.POST("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.SaveUploadedFile(file, dst)
})
// Multiple files upload
r.POST("/upload-multiple", func(c *gin.Context) {
form, _ := c.MultipartForm()
files := form.File["files"]
for _, file := range files {
c.SaveUploadedFile(file, dst)
}
})
Responses
Response Types
Different types of responses in Gin
Gin
func main() {
r := gin.Default()
// JSON response
r.GET("/json", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "JSON response",
"status": "success",
})
})
// XML response
r.GET("/xml", func(c *gin.Context) {
c.XML(http.StatusOK, gin.H{
"message": "XML response",
"status": "success",
})
})
// YAML response
r.GET("/yaml", func(c *gin.Context) {
c.YAML(http.StatusOK, gin.H{
"message": "YAML response",
"status": "success",
})
})
// File download
r.GET("/download", func(c *gin.Context) {
c.File("path/to/file.pdf")
})
// Static files
r.Static("/static", "./static")
r.StaticFile("/favicon.ico", "./favicon.ico")
}
Response Headers
Setting response headers in Gin
Gin
func main() {
r := gin.Default()
r.GET("/headers", func(c *gin.Context) {
// Set headers
c.Header("Content-Type", "application/json")
c.Header("X-Custom-Header", "value")
// Set multiple headers
c.Header("Cache-Control", "no-cache, no-store, must-revalidate")
c.Header("Pragma", "no-cache")
c.Header("Expires", "0")
c.JSON(http.StatusOK, gin.H{"message": "success"})
})
}
Middleware
Custom Middleware
Creating and using custom middleware
Gin
// Logger middleware
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
// Set example variable
c.Set("example", "12345")
// before request
c.Next()
// after request
latency := time.Since(t)
log.Print(latency)
// access the status we are sending
status := c.Writer.Status()
log.Println(status)
}
}
// Auth middleware
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
c.Abort()
return
}
c.Next()
}
}
func main() {
r := gin.Default()
r.Use(Logger())
r.Use(AuthRequired())
}
Error Handling
Error handling and recovery in Gin
Gin
// Custom error handler
func ErrorHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
c.JSON(http.StatusInternalServerError, gin.H{
"errors": c.Errors.Errors(),
})
}
}
}
func main() {
r := gin.Default()
r.Use(ErrorHandler())
// Error example
r.GET("/error", func(c *gin.Context) {
c.Error(errors.New("something went wrong"))
})
// Panic recovery
r.GET("/panic", func(c *gin.Context) {
panic("intentional panic")
})
}
Gin - Interactive Developer Reference
Hover over code blocks to copy or run in live playground