go get -u github.com/gin-gonic/gin | Gin 설치 |
go mod init myapp | 모듈 초기화 |
go run main.go | 서버 실행 |
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Hello World"})
})
r.Run(":8080")
} // Path parameter
r.GET("/user/:id", func(c *gin.Context) {
id := c.Param("id")
c.JSON(200, gin.H{"id": id})
})
// Query parameter
r.GET("/search", func(c *gin.Context) {
q := c.DefaultQuery("q", "")
page := c.Query("page")
c.JSON(200, gin.H{"q": q, "page": page})
}) r.GET("/resource", getHandler)
r.POST("/resource", createHandler)
r.PUT("/resource/:id", updateHandler)
r.PATCH("/resource/:id", patchHandler)
r.DELETE("/resource/:id", deleteHandler)
r.HEAD("/resource", headHandler)
r.OPTIONS("/resource", optionsHandler)
// Any method
r.Any("/any", anyHandler)
// Custom methods
r.Handle("CUSTOM", "/custom", handler) api := r.Group("/api")
{
api.GET("/users", getUsers)
api.POST("/users", createUser)
v1 := api.Group("/v1")
{
v1.GET("/items", getItems)
}
}
// With middleware
authorized := r.Group("/admin")
authorized.Use(AuthMiddleware())
{
authorized.GET("/dashboard", dashboard)
} type CreateUser struct {
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
Age int `json:"age" binding:"gte=0,lte=120"`
}
func createUser(c *gin.Context) {
var user CreateUser
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, user)
} type LoginForm struct {
Username string `form:"username" binding:"required"`
Password string `form:"password" binding:"required"`
}
func login(c *gin.Context) {
var form LoginForm
if err := c.ShouldBind(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// Process login
}
// File upload
func upload(c *gin.Context) {
file, _ := c.FormFile("file")
c.SaveUploadedFile(file, "uploads/"+file.Filename)
} // JSON
c.JSON(200, gin.H{"status": "ok"})
c.JSON(200, user) // struct
// IndentedJSON (pretty)
c.IndentedJSON(200, data)
// SecureJSON (prevents JSON hijacking)
c.SecureJSON(200, []string{"a", "b"})
// JSONP
c.JSONP(200, gin.H{"data": "value"}) // String
c.String(200, "Hello %s", name)
// HTML
c.HTML(200, "index.html", gin.H{"title": "Home"})
// XML
c.XML(200, gin.H{"message": "ok"})
// YAML
c.YAML(200, gin.H{"message": "ok"})
// File
c.File("./files/doc.pdf")
c.FileAttachment("./files/doc.pdf", "document.pdf")
// Redirect
c.Redirect(301, "/new-path") func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
// Before request
c.Set("start", t)
c.Next() // Process request
// After request
latency := time.Since(t)
log.Printf("Latency: %v", latency)
}
}
// Use globally
r.Use(Logger())
// Use on route
r.GET("/", Logger(), handler) // Logger & Recovery (included in Default())
r := gin.New()
r.Use(gin.Logger())
r.Use(gin.Recovery())
// Basic Auth
authorized := r.Group("/admin")
authorized.Use(gin.BasicAuth(gin.Accounts{
"admin": "secret",
}))
// CORS (use gin-contrib/cors)
import "github.com/gin-contrib/cors"
r.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"},
AllowMethods: []string{"GET", "POST"},
}))