### Create First Gin Application
Source: https://gin-gonic.com/zh-cn/docs
This Go code demonstrates the creation of a basic Gin web application. It initializes a Gin router with default middleware (logging and recovery), defines a simple GET route '/ping' that responds with JSON, and starts the HTTP server on port 8080. This serves as a 'Hello, World!' equivalent for Gin.
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
// 创建带默认中间件(日志与恢复)的 Gin 路由器
r := gin.Default()
// 定义简单的 GET 路由
r.GET("/ping", func(c *gin.Context) {
// 返回 JSON 响应
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
// 默认端口 8080 启动服务器
// 监听 0.0.0.0:8080(Windows 下为 localhost:8080)
r.Run()
}
```
--------------------------------
### Gin Middleware Execution Flow Example
Source: https://gin-gonic.com/zh-cn/blog/news/how-to-build-one-effective-middleware
This Go code sets up a Gin application with multiple middleware functions and a handler. It illustrates the order of execution for both middleware initialization and request processing. Dependencies: 'gin-gonic/gin', 'fmt'. This example is crucial for understanding how middleware chains are processed.
```go
func main() {
router := gin.Default()
router.Use(globalMiddleware())
router.GET("/rest/n/api/*some", mid1(), mid2(), handler)
router.Run()
}
func globalMiddleware() gin.HandlerFunc {
fmt.Println("globalMiddleware...1")
return func(c *gin.Context) {
fmt.Println("globalMiddleware...2")
c.Next()
fmt.Println("globalMiddleware...3")
}
}
func handler(c *gin.Context) {
fmt.Println("exec handler.")
}
func mid1() gin.HandlerFunc {
fmt.Println("mid1...1")
return func(c *gin.Context) {
fmt.Println("mid1...2")
c.Next()
fmt.Println("mid1...3")
}
}
func mid2() gin.HandlerFunc {
fmt.Println("mid2...1")
return func(c *gin.Context) {
fmt.Println("mid2...2")
c.Next()
fmt.Println("mid2...3")
}
}
```
--------------------------------
### Install Gin Gonic Web Framework
Source: https://gin-gonic.com/zh-cn/docs
This code snippet shows how to import the Gin Gonic framework into your Go project using Go modules. Go will automatically download the necessary package during the build process. This is the standard way to include Gin in your project.
```go
import "github.com/gin-gonic/gin"
```
--------------------------------
### HTTP/2 Server Push with Gin Framework
Source: https://gin-gonic.com/zh-cn/docs/examples/http2-server-push
Complete example of implementing HTTP/2 server push using Gin framework. The code sets up an HTTPS server that serves an HTML template and uses the Pusher interface to push JavaScript assets to the client. Requires Go 1.8+ and valid TLS certificate/key files.
```go
package main
import (
"html/template"
"log"
"github.com/gin-gonic/gin"
)
var html = template.Must(template.New("https").Parse(`
Https Test
Welcome, Ginner!
`))
func main() {
router := gin.Default()
router.Static("/assets", "./assets")
router.SetHTMLTemplate(html)
router.GET("/", func(c *gin.Context) {
if pusher := c.Writer.Pusher(); pusher != nil {
// Use pusher.Push() for server push
if err := pusher.Push("/assets/app.js", nil); err != nil {
log.Printf("Failed to push: %v", err)
}
}
c.HTML(200, "https", gin.H{
"status": "success",
})
})
// Listen and start server on https://127.0.0.1:8080
router.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
}
```
--------------------------------
### 为 Gin 路由编写测试用例 (Go)
Source: https://gin-gonic.com/zh-cn/docs/testing
使用 Go 的 net/http/httptest 包为 Gin 框架的 /ping GET 路由和 /user/add POST 路由编写测试用例。这些测试验证了路由的响应码和响应体。
```go
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPingRoute(t *testing.T) {
router := setupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/ping", nil)
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
assert.Equal(t, "pong", w.Body.String())
}
// Test for POST /user/add
func TestPostUser(t *testing.T) {
router := setupRouter()
router = postUser(router)
w := httptest.NewRecorder()
// Create an example user for testing
exampleUser := User{
Username: "test_name",
Gender: "male",
}
userJson, _ := json.Marshal(exampleUser)
req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
// Compare the response body with the json data of exampleUser
assert.Equal(t, string(userJson), w.Body.String())
}
```
--------------------------------
### Customize Autocert Manager for Let's Encrypt (Go)
Source: https://gin-gonic.com/zh-cn/docs/examples/support-lets-encrypt
This example shows how to configure a custom autocert manager for Let's Encrypt integration. It allows for more control over certificate caching, host policies, and accepting terms of service. Requires 'autotls' and 'golang.org/x/crypto/acme/autocert' packages.
```go
package main
import (
"log"
"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/acme/autocert"
)
func main() {
router := gin.Default()
// Ping handler
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
m := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
Cache: autocert.DirCache("/var/www/.cache"),
}
log.Fatal(autotls.RunWithManager(r, &m))
}
```
--------------------------------
### Test File Upload with Curl
Source: https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file
This command demonstrates how to use `curl` to send a multipart/form-data POST request to a Gin Gonic server for file uploads. It specifies the target URL, the file to be uploaded using the `@` symbol, and sets the appropriate Content-Type header. This is useful for testing the file upload endpoint.
```bash
curl -X POST http://localhost:8080/upload \
-F "file=@/Users/appleboy/test.zip" \
-H "Content-Type: multipart/form-data"
```
--------------------------------
### Test Query String Binding with curl
Source: https://gin-gonic.com/zh-cn/docs/examples/bind-query-or-post
This command-line snippet shows how to test the Gin application's query string binding functionality. It uses `curl` to send a GET request to the `/testing` endpoint with query parameters for `name`, `address`, and `birthday`.
```bash
$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
```
--------------------------------
### Handle Single File Upload with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file
This Go code snippet shows how to set up a Gin Gonic server to handle single file uploads. It configures the maximum multipart memory and defines a POST route '/upload' to receive and save the uploaded file. The code depends on the 'gin' and 'log' packages. It takes multipart form data with a 'file' field as input and saves the file to the server, returning a success message.
```go
func main() {
router := gin.Default()
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
log.Println(file.Filename)
dst := "./file" + file.Filename
// 上传文件至指定的完整文件路径
c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
router.Run(":8080")
}
```
--------------------------------
### Curl Commands for Testing Gin Data Binding
Source: https://gin-gonic.com/zh-cn/docs/examples/bind-form-data-request-with-custom-struct
These `curl` commands demonstrate how to send GET requests with query parameters to the Gin server endpoints defined in the Go code. They show the expected JSON output when form data is successfully bound to the custom structs.
```bash
$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
```
--------------------------------
### Multipart/Urlencoded Form Binding with Gin
Source: https://gin-gonic.com/zh-cn/docs/examples/multipart-urlencoded-binding
Demonstrates binding multipart/urlencoded form data to a struct in Gin with validation. The example shows a login form that uses struct tags for field mapping and validation rules, automatically selecting the appropriate binding method via ShouldBind.
```go
package main
import (
"github.com/gin-gonic/gin"
)
type LoginForm struct {
User string `form:"user" binding:"required"`
Password string `form:"password" binding:"required"`
}
func main() {
router := gin.Default()
router.POST("/login", func(c *gin.Context) {
// You can use explicit binding declaration for multipart form:
// c.ShouldBindWith(&form, binding.Form)
// Or simply use ShouldBind method for automatic binding:
var form LoginForm
// In this case, the appropriate binding will be automatically selected
if c.ShouldBind(&form) == nil {
if form.User == "user" && form.Password == "password" {
c.JSON(200, gin.H{"status": "you are logged in"})
} else {
c.JSON(401, gin.H{"status": "unauthorized"})
}
}
})
router.Run(":8080")
}
```
--------------------------------
### Bind and Validate URI Parameters in Gin
Source: https://gin-gonic.com/zh-cn/docs/examples/bind-uri
This example shows how to define a struct with URI binding tags and use ShouldBindUri to extract and validate path parameters from a GET request. The Person struct uses uri tags with required and uuid validators to ensure the ID is a valid UUID format. Errors are returned as JSON with a 400 status code, and successful bindings return the parsed data with a 200 status code.
```go
package main
import "github.com/gin-gonic/gin"
type Person struct {
ID string `uri:"id" binding:"required,uuid"`
Name string `uri:"name" binding:"required"`
}
func main() {
route := gin.Default()
route.GET("/:name/:id", func(c *gin.Context) {
var person Person
if err := c.ShouldBindUri(&person); err != nil {
c.JSON(400, gin.H{"msg": err.Error()})
return
}
c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
})
route.Run(":8088")
}
```
--------------------------------
### 加载不同目录下同名模板 - Go
Source: https://gin-gonic.com/zh-cn/docs/examples/html-rendering
当项目中使用不同目录下的同名模板时,Gin Gonic 的 LoadHTMLGlob 方法支持通过 glob 模式(例如 "templates/**/*")递归加载所有模板。这使得在处理复杂的项目结构时,可以方便地管理和渲染来自不同路径的模板。
```Go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/**/*")
router.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "Posts",
})
})
router.GET("/users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "Users",
})
})
router.Run(":8080")
}
```
--------------------------------
### Set and Get Cookie in Gin Gonic (Go)
Source: https://gin-gonic.com/zh-cn/docs/examples/cookie
This Go code snippet demonstrates how to set a cookie named 'gin_cookie' with a value 'test' and an expiration time of 3600 seconds. It also shows how to retrieve the cookie's value. If the cookie is not found, it's set.
```go
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/cookie", func(c *gin.Context) {
cookie, err := c.Cookie("gin_cookie")
if err != nil {
cookie = "NotSet"
c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
}
fmt.Printf("Cookie value: %s \n", cookie)
})
router.Run()
}
```
--------------------------------
### Go Gin BasicAuth 中间件实现
Source: https://gin-gonic.com/zh-cn/docs/examples/using-basicauth-middleware
此代码片段演示了如何在 Go 的 Gin Web 框架中使用 BasicAuth 中间件。它设置了一个受保护的路由组 `/admin`,并定义了一个 `/secrets` 端点,只有提供有效凭据的用户才能访问。代码中模拟了敏感数据,并通过 `gin.AuthUserKey` 从上下文中检索已认证的用户。
```go
// 模拟一些私人数据
var secrets = gin.H{
"foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
"austin": gin.H{"email": "austin@example.com", "phone": "666"},
"lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
}
func main() {
router := gin.Default()
// 路由组使用 gin.BasicAuth() 中间件
// gin.Accounts 是 map[string]string 的一种快捷方式
authorized := router.Group("/admin", gin.BasicAuth(gin.Accounts{
"foo": "bar",
"austin": "1234",
"lena": "hello2",
"manu": "4321",
}))
// /admin/secrets 端点
// 触发 "localhost:8080/admin/secrets
authorized.GET("/secrets", func(c *gin.Context) {
// 获取用户,它是由 BasicAuth 中间件设置的
user := c.MustGet(gin.AuthUserKey).(string)
if secret, ok := secrets[user]; ok {
c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
} else {
c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
}
})
// 监听并在 0.0.0.0:8080 上启动服务
router.Run(":8080")
}
```
--------------------------------
### Delete Cookie in Gin Gonic (Go)
Source: https://gin-gonic.com/zh-cn/docs/examples/cookie
This Go code snippet shows how to delete a cookie named 'gin_cookie' in a Gin Gonic application. Deletion is achieved by setting the 'Max-Age' attribute of the cookie to -1.
```go
c.SetCookie("gin_cookie", "test", -1, "/", "localhost", false, true)
```
--------------------------------
### 获取 Gin 完整示例代码
Source: https://gin-gonic.com/zh-cn/docs/quickstart
此命令使用 `curl` 从 GitHub 下载 Gin 的一个更完整的 `basic` 示例到本地的 `main.go` 文件中。适用于需要更复杂功能的场景。
```bash
curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
```
--------------------------------
### 编写第一个 Gin 应用
Source: https://gin-gonic.com/zh-cn/docs/quickstart
此代码块展示了如何创建一个 `main.go` 文件并编写一个基本的 Gin 应用程序。该应用启动一个 HTTP 服务器,并在 `/ping` 路径上响应 JSON 消息。
```go
package main
import "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
router.Run() // 默认监听 0.0.0.0:8080
}
```
--------------------------------
### 加载 HTML 模板文件 - Go
Source: https://gin-gonic.com/zh-cn/docs/examples/html-rendering
使用 LoadHTMLGlob 或 LoadHTMLFiles 方法加载 HTML 模板。LoadHTMLGlob 支持 glob 模式匹配,可以一次性加载多个模板文件。LoadHTMLFiles 则用于加载指定的多个模板文件。这些方法允许您将 HTML 渲染到 HTTP 响应中。
```Go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
router.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "Main website",
})
})
router.Run(":8080")
}
```
--------------------------------
### Gin Gonic: 匹配和提取路由参数
Source: https://gin-gonic.com/zh-cn/docs/examples/param-in-path
此代码片段演示了如何在 Gin Gonic 中定义路由以匹配 URL 中的参数。它展示了如何使用 ':name' 捕获单个参数,以及如何使用 ':name/*action' 捕获带通配符的路径段。捕获的参数可以通过 c.Param() 方法访问。此示例需要 'net/http' 和 'github.com/gin-gonic/gin' 库。
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// 此 handler 将匹配 /user/john 但不会匹配 /user/ 或者 /user
router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, "Hello %s", name)
})
// 此 handler 将匹配 /user/john/ 和 /user/john/send
// 如果没有其他路由匹配 /user/john,它将重定向到 /user/john/
router.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
})
router.Run(":8080")
}
```
--------------------------------
### Gin Middleware Initialization and Request Handling
Source: https://gin-gonic.com/zh-cn/blog/news/how-to-build-one-effective-middleware
This Go code defines a Gin middleware function that separates initialization logic (executed once) from request handling logic (executed for each request). It demonstrates setting a value in the context during initialization and accessing it during a request. Dependencies: 'gin-gonic/gin'. Input: 'params string'. Output: 'gin.HandlerFunc'.
```go
func funcName(params string) gin.HandlerFunc {
// <--- First part: Initialization
// Initialize example: validate input parameters
if err := check(params); err != nil {
panic(err)
}
return func(c *gin.Context) {
// <--- Second part: Per-request execution
// Execute for each request: inject into context
c.Set("TestVar", params)
c.Next()
}
}
```
--------------------------------
### 自定义 HTML 模板渲染器 - Go
Source: https://gin-gonic.com/zh-cn/docs/examples/html-rendering
Gin Gonic 允许你使用自定义的 HTML 模板渲染器。通过 `template.Must(template.ParseFiles(...))` 创建一个 `*template.Template` 对象,然后使用 `router.SetHTMLTemplate()` 方法将其设置给 Gin 路由器。这提供了对模板解析和管理的更高控制权。
```Go
package main
import (
"html/template"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
html := template.Must(template.ParseFiles("file1", "file2"))
outer.SetHTMLTemplate(html)
router.Run(":8080")
}
```
--------------------------------
### 运行 Gin API 服务
Source: https://gin-gonic.com/zh-cn/docs/quickstart
此代码块展示了如何使用 `go run` 命令来启动之前编写的 Gin API 服务。服务启动后,可以通过访问指定的 URL 来测试 API。
```bash
go run main.go
```
--------------------------------
### ShouldBindQuery - Bind URL Query Parameters in Gin Go
Source: https://gin-gonic.com/zh-cn/docs/examples/only-bind-query-string
This example shows how to use ShouldBindQuery to bind only URL query string parameters to a struct while ignoring POST data. The Person struct defines form tags for mapping query parameters. The function returns nil on successful binding, allowing validation of the binding result.
```go
package main
import (
"log"
"github.com/gin-gonic/gin"
)
type Person struct {
Name string `form:"name"`
Address string `form:"address"`
}
func main() {
route := gin.Default()
route.Any("/testing", startPage)
route.Run(":8085")
}
func startPage(c *gin.Context) {
var person Person
if c.ShouldBindQuery(&person) == nil {
log.Println("====== Only Bind By Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, "Success")
}
```
--------------------------------
### 配置 Gin 服务器端口和绑定地址 (Go)
Source: https://gin-gonic.com/zh-cn/docs/deployment
演示如何使用 `router.Run()` 启动 Gin 服务器,包括默认绑定所有接口并监听 8080 端口,指定绑定地址和端口,仅指定监听端口,以及如何通过 `PORT` 环境变量动态更改监听端口。
```go
router := gin.Default()
router.Run()
```
```go
router := gin.Default()
router.Run("192.168.1.100:8080")
```
```go
router := gin.Default()
router.Run(":8080")
```
--------------------------------
### 自定义模板函数 - Go
Source: https://gin-gonic.com/zh-cn/docs/examples/html-rendering
Gin Gonic 支持为 HTML 模板注册自定义函数。通过 `template.FuncMap` 和 `router.SetFuncMap()` 方法,可以将 Go 函数暴露给模板使用。这允许在模板中执行更复杂的逻辑,例如格式化日期。
```Go
package main
import (
"fmt"
html "html/template"
"net/http"
time "time"
"github.com/gin-gonic/gin"
)
func formatAsDate(t time.Time) string {
year, month, day := t.Date()
return fmt.Sprintf("%d/%02d/%02d", year, month, day)
}
func main() {
router := gin.Default()
router.Delims("{[{", "}]}")
router.SetFuncMap(html.FuncMap{
"formatAsDate": formatAsDate,
})
router.LoadHTMLFiles("./testdata/template/raw.tmpl")
router.GET("/raw", func(c *gin.Context) {
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
})
})
router.Run(":8080")
}
```
--------------------------------
### Bind Query String/Form Data to Struct in Go (Gin)
Source: https://gin-gonic.com/zh-cn/docs/examples/bind-query-or-post
This Go code snippet demonstrates how to bind query string or form data to a Go struct using the Gin framework. It defines a `Person` struct with `form` tags for binding and a handler function that binds the incoming request data to the struct. The handler logs the bound fields and returns a success message. It handles GET requests using query parameters and POST requests with JSON, XML, or form-data.
```go
package main
import (
"log"
"time"
"github.com/gin-gonic/gin"
)
type Person struct {
Name string `form:"name"`
Address string `form:"address"`
Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}
func main() {
route := gin.Default()
route.GET("/testing", startPage)
route.Run(":8085")
}
func startPage(c *gin.Context) {
var person Person
// 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
// 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON` 或 `XML`,然后再使用 `Form`(`form-data`)。
// 查看更多:https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L88
if c.ShouldBind(&person) == nil {
log.Println(person.Name)
log.Println(person.Address)
log.Println(person.Birthday)
}
c.String(200, "Success")
}
```
--------------------------------
### Run Gin Application
Source: https://gin-gonic.com/zh-cn/docs
These shell commands show how to save the Go code into a file named 'main.go' and then run the Gin application using the Go runtime. After running, the application can be accessed via a web browser.
```bash
go run main.go
```
--------------------------------
### Gin DataFromReader 方法处理流式数据响应
Source: https://gin-gonic.com/zh-cn/docs/examples/serving-data-from-reader
使用 Gin 框架的 DataFromReader 方法从 HTTP 响应体流式读取数据并返回给客户端。该示例展示如何获取远程文件、验证响应状态、提取响应元数据(内容长度和类型),并通过自定义响应头实现文件下载功能。适用于代理、文件转发等场景。
```go
func main() {
router := gin.Default()
router.GET("/someDataFromReader", func(c *gin.Context) {
response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
if err != nil || response.StatusCode != http.StatusOK {
c.Status(http.StatusServiceUnavailable)
return
}
reader := response.Body
contentLength := response.ContentLength
contentType := response.Header.Get("Content-Type")
extraHeaders := map[string]string{
"Content-Disposition": `attachment; filename="gopher.png"`,
}
c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
})
router.Run(":8080")
}
```
--------------------------------
### Render Protocol Buffers Response with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/rendering
Demonstrates rendering Protocol Buffers data with Gin Gonic. This involves defining a Protobuf message structure (in `testdata/protoexample`) and then using `c.ProtoBuf` to serialize and send the binary data.
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"path/to/your/protoexample" // Assuming protoexample is defined elsewhere
)
func main() {
router := gin.Default()
router.GET("/someProtoBuf", func(c *gin.Context) {
reps := []int64{int64(1), int64(2)}
label := "test"
// The specific protobuf definition is in testdata/protoexample.
data := &protoexample.Test{
Label: &label,
Reps: reps,
}
// Note that the data in the response becomes binary
// Will output data serialized by protoexample.Test protobuf
c.ProtoBuf(http.StatusOK, data)
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
```
--------------------------------
### Gin 框架 HTTP 方法路由定义
Source: https://gin-gonic.com/zh-cn/docs/examples/http-method
使用 Gin Web 框架定义支持多种 HTTP 方法(GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS)的路由处理器。该示例创建默认路由器(包含 logger 和 recovery 中间件),映射各个 HTTP 方法到相应的处理函数,并在 8080 端口(或环境变量指定的端口)启动服务器。
```Go
func main() {
// 禁用控制台颜色
// gin.DisableConsoleColor()
// 使用默认中间件(logger 和 recovery 中间件)创建 gin 路由
router := gin.Default()
router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)
// 默认在 8080 端口启动服务,除非定义了一个 PORT 的环境变量。
router.Run()
// router.Run(":3000") hardcode 端口号
}
```
--------------------------------
### Embed Static Assets with Gin Gonic (Go)
Source: https://gin-gonic.com/zh-cn/docs/examples/bind-single-binary-with-template
This Go code snippet shows how to embed static assets into a Gin Gonic web application. It uses the `embed.FS` functionality to serve HTML templates and static files (like images and icons) directly from the compiled binary. This approach simplifies deployment by eliminating the need for separate static file directories.
```go
package main
import (
"embed"
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
//go:embed templates/*.tmpl templates/foo/*.tmpl
var f embed.FS
func main() {
router := gin.Default()
templ := template.Must(template.New("").ParseFS(f, "templates/*.tmpl", "templates/foo/*.tmpl"))
router.SetHTMLTemplate(templ)
// example: /public/assets/images/example.png
router.StaticFS("/public", http.FS(f))
router.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "Main website",
})
})
router.GET("/foo", func(c *gin.Context) {
c.HTML(http.StatusOK, "bar.tmpl", gin.H{
"title": "Foo website",
})
})
router.GET("favicon.ico", func(c *gin.Context) {
file, _ := f.ReadFile("assets/favicon.ico")
c.Data(
http.StatusOK,
"image/x-icon",
file,
)
})
router.Run(":8080")
}
```
--------------------------------
### Go: JSON、XML、表单绑定与验证
Source: https://gin-gonic.com/zh-cn/docs/examples/binding-and-validation
此代码演示了如何使用 Gin Gonic 框架将请求体绑定到 Go 结构体,并进行字段验证。它支持 JSON、XML 和 HTML 表单数据的绑定,并处理绑定错误。结构体字段通过 `binding` 标签定义了验证规则(如 `required`)。
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// 登录结构体,定义了需要绑定的字段及其验证规则
type Login struct {
User string `form:"user" json:"user" xml:"user" binding:"required"
Password string `form:"password" json:"password" xml:"password" binding:"required"
}
func main() {
router := gin.Default()
// 绑定 JSON
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if json.User != "manu" || json.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// 绑定 XML
router.POST("/loginXML", func(c *gin.Context) {
var xml Login
if err := c.ShouldBindXML(&xml); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if xml.User != "manu" || xml.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// 绑定 HTML 表单
router.POST("/loginForm", func(c *gin.Context) {
var form Login
// 根据 Content-Type Header 推断使用哪个绑定器。
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if form.User != "manu" || form.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
// 监听并在 0.0.0.0:8080 上启动服务
router.Run(":8080")
}
```
--------------------------------
### Graceful Shutdown with fvbock/endless Library
Source: https://gin-gonic.com/zh-cn/docs/examples/graceful-restart-or-stop
Replaces the default ListenAndServe with fvbock/endless to handle graceful server shutdown. This approach requires an external library but provides a simple wrapper around the standard server startup. Refer to issue #296 for additional context.
```go
router := gin.Default()
router.GET("/", handler)
endless.ListenAndServe(":4242", router)
```
--------------------------------
### 安装 Gin 并初始化 Go 项目
Source: https://gin-gonic.com/zh-cn/docs/quickstart
此代码块展示了如何创建项目文件夹、初始化 Go 模块以及安装 Gin Web 框架的依赖。需要 Go 1.23 或更高版本。
```bash
mkdir gin-quickstart && cd gin-quickstart
go mod init gin-quickstart
go get -u github.com/gin-gonic/gin
```
--------------------------------
### 创建和使用 Gin Gonic 自定义中间件
Source: https://gin-gonic.com/zh-cn/docs/examples/custom-middleware
此代码演示了如何在 Gin Gonic Web 框架中创建自定义中间件。Logger 中间件会在请求处理前后记录处理时间,并可以设置和获取请求上下文中的变量。它需要 Gin 框架作为依赖。
```go
package main
import (
"log"
"time"
"github.com/gin-gonic/gin"
)
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
// 设置 example 变量
c.Set("example", "12345")
// 请求前
c.Next()
// 请求后
latency := time.Since(t)
log.Print(latency)
// 获取发送的 status
status := c.Writer.Status()
log.Println(status)
}
}
func main() {
r := gin.New()
r.Use(Logger())
r.GET("/test", func(c *gin.Context) {
example := c.MustGet("example").(string)
// 打印:"12345"
log.Println(example)
})
// 监听并在 0.0.0.0:8080 上启动服务
r.Run(":8080")
}
```
--------------------------------
### Enable Let's Encrypt HTTPS with One Line (Go)
Source: https://gin-gonic.com/zh-cn/docs/examples/support-lets-encrypt
This snippet demonstrates the simplest way to enable Let's Encrypt HTTPS for your Gin Gonic server. It automatically obtains and renews certificates for the specified domains. Requires the 'autotls' package.
```go
package main
import (
"log"
"github.com/gin-gonic/autotls"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// Ping handler
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
log.Fatal(autotls.Run(router, "example1.com", "example2.com"))
}
```
--------------------------------
### Render YAML Response with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/rendering
Illustrates how to serve YAML data using Gin Gonic. The `c.YAML` method serializes the provided data structure (like `gin.H`) into YAML format and sends it as the response.
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/someYAML", func(c *gin.Context) {
c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
router.Run(":8080")
}
```
--------------------------------
### Render XML Response with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/rendering
Shows how to render an XML response using the Gin Gonic framework. Similar to JSON rendering, it uses `c.XML` and can accept `gin.H` or other data structures that can be marshaled into XML.
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/someXML", func(c *gin.Context) {
c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
router.Run(":8080")
}
```
--------------------------------
### Render JSON Response with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/rendering
Demonstrates rendering JSON responses using Gin Gonic. It shows how to use `gin.H` (a map) and Go structs to define the JSON payload. The `c.JSON` function handles the serialization and sets the appropriate Content-Type header.
```go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// gin.H is a shortcut for map[string]interface{}
router.GET("/someJSON", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
router.GET("/moreJSON", func(c *gin.Context) {
// You can also use a struct
var msg struct {
Name string `json:"user"`
Message string
Number int
}
msg.Name = "Lena"
msg.Message = "hey"
msg.Number = 123
// Note that msg.Name is now in the JSON as "user"
// Will output: {"user": "Lena", "Message": "hey", "Number": 123}
c.JSON(http.StatusOK, msg)
})
router.Run(":8080")
}
```
--------------------------------
### Gin 结合 net/http 使用常量
Source: https://gin-gonic.com/zh-cn/docs/quickstart
此代码块展示了如何在 Gin 应用中使用 `net/http` 包中的常量来表示 HTTP 响应码,例如 `http.StatusOK`。这有助于提高代码的可读性。
```go
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
router.Run()
}
```
--------------------------------
### Graceful Shutdown with Go 1.8+ http.Server.Shutdown()
Source: https://gin-gonic.com/zh-cn/docs/examples/graceful-restart-or-stop
Implements graceful shutdown using Go 1.8's built-in http.Server.Shutdown() method with signal handling. The server listens for SIGINT and SIGTERM signals, then gracefully shuts down with a 5-second timeout to allow existing connections to complete. This approach eliminates the need for external libraries.
```go
//go:build go1.8
// +build go1.8
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
time.Sleep(5 * time.Second)
c.String(http.StatusOK, "Welcome Gin Server")
})
srv := &http.Server{
Addr: ":8080",
Handler: router.Handler(),
}
go func() {
// service connections
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal, 1)
// kill (no params) by default sends syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be caught, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutdown Server ...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Println("Server Shutdown:", err)
}
log.Println("Server exiting")
}
```
--------------------------------
### Shell: 示例 POST 请求与错误响应
Source: https://gin-gonic.com/zh-cn/docs/examples/binding-and-validation
此 Shell 命令演示了如何使用 `curl` 工具向 Gin Gonic 服务器发送一个 JSON POST 请求,该请求缺少必填字段 `Password`。它展示了服务器返回的 400 Bad Request 错误响应,其中包含详细的验证错误信息。
```bash
$ curl -v -X POST \
http://localhost:8080/loginJSON \
-H 'content-type: application/json' \
-d '{ "user": "manu" }'
> POST /loginJSON HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: */*
> content-type: application/json
> Content-Length: 18
>
* upload completely sent off: 18 out of 18 bytes
< HTTP/1.1 400 Bad Request
< Content-Type: application/json; charset=utf-8
< Date: Fri, 04 Aug 2017 03:51:31 GMT
< Content-Length: 100
>
{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
```
--------------------------------
### Go: 强制 Gin 控制台日志颜色输出
Source: https://gin-gonic.com/zh-cn/docs/examples/controlling-log-output-coloring
此代码示例展示了如何在 Go 语言中使用 Gin 框架强制启用控制台日志的颜色输出。通过调用 `gin.ForceConsoleColor()` 函数,可以确保日志在终端始终以彩色显示,即使在自动检测可能禁用颜色的环境中。这有助于提高日志的可读性。
```go
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 强制日志颜色化
gin.ForceConsoleColor()
// 用默认中间件创建一个 gin 路由:
// 日志和恢复(无崩溃)中间件
router := gin.Default()
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
router.Run(":8080")
}
```
--------------------------------
### Test Security Headers with Curl (Shell)
Source: https://gin-gonic.com/zh-cn/docs/examples/security-headers
These shell commands demonstrate how to test the security headers implemented in the Gin application using `curl`. The first command checks the headers for a valid request, and the second tests the protection against host header injection by sending a request with an invalid host.
```shell
# 检查页眉
curl localhost:8080/ping -I
# 检查主机标头注入
curl localhost:8080/ping -I -H "Host:neti.ee"
```
--------------------------------
### Perform POST HTTP Redirect with Gin Gonic
Source: https://gin-gonic.com/zh-cn/docs/examples/redirects
This snippet shows how to perform an HTTP redirect via a POST request. It uses `http.StatusFound` (302) and redirects to an internal path. This addresses specific routing requirements and issue #444.
```go
router.POST("/test", func(c *gin.Context) {
c.Redirect(http.StatusFound, "/foo")
})
```
--------------------------------
### Test Multiple File Uploads using Curl
Source: https://gin-gonic.com/zh-cn/docs/examples/upload-file/multiple-file
This command demonstrates how to use `curl` to send multiple files to the `/upload` endpoint of a Gin Gonic application. It specifies the POST method, the target URL, and uses the `-F` flag to upload two files (`test1.zip` and `test2.zip`) associated with the `upload[]` form field. The `-H` flag sets the `Content-Type` header.
```bash
curl -X POST http://localhost:8080/upload \
-F "upload[]=@/Users/appleboy/test1.zip" \
-F "upload[]=@/Users/appleboy/test2.zip" \
-H "Content-Type: multipart/form-data"
```