GO:Hello Gin 1.基础篇

222 阅读7分钟

写在前面

基本上是在gin官网copy示例过来的,多了一点点注释。预计五篇系列文章,基础、入门、进阶、高级篇内容把gin官网上的示例都写一下。最后一篇把前四篇的知识串起来实现一个基于gin的静态资源服务。

go环境需要提前安装好,没装可以参考Ubuntu22安装golang。Mac和win流程可以自行百度

基础知识

什么是Gin?

Gin是一个用Go (Golang) 编写的HTTP web框架。它是一个类似于martini但拥有更好性能的API框架,由于使用了httprouter,速度提高了近40倍。Gin是一个非常小巧且高效的框架,提供了一组丰富的功能,包括路由、中间件支持、渲染、自定义验证器等,旨在构建高性能的Web应用和微服务。

Gin的设计哲学

Gin的设计哲学主要集中在以下几个方面:

  • 性能:Gin使用自定义的路由器,替代了Go标准库中的http.ServeMux。这使得Gin在性能上有显著提升,特别是在解析和处理路由方面。
  • 简易性:Gin旨在提供一个简洁的API,使得开发者能够快速上手并构建应用。其API设计简单直观,容易理解和使用。
  • 模块化和中间件:Gin支持通过中间件来扩展功能,使得开发者可以轻松地为其应用添加新的功能,如日志记录、请求限制、跨域资源共享等。
  • 错误管理:Gin提供了一种集中式的错误处理机制,使得错误管理变得更加简单和一致。

其他Go Web框架

除了Gin之外,Go语言还有许多其他优秀的Web框架,每个框架都有其特点和用途,适用于不同的项目需求。以下是一些流行的Go Web框架:

Echo:Echo是一个高性能、极简的Go Web框架,提供了一组丰富的特性,如路由、中间件支持、数据绑定、数据验证等。Echo特别注重性能和内存优化,适用于构建高性能的Web应用。

Beego:Beego是一个全栈MVC框架,提供了从数据库操作到缓存、日志等几乎所有Web应用开发所需的功能。Beego特别适合于快速开发大型Web应用。

Fiber:Fiber是一个灵感来自于Express.js的Web框架,它旨在简化HTTP应用程序的开发过程,同时提供Express.js那样的开发体验。Fiber以其极简的API和高性能而著称。

GoFrame (gf):GoFrame是一个模块化、高性能、企业级的Go应用开发框架。它提供了MVC模式、数据库ORM、配置管理、日志记录、缓存管理等一系列的开发组件和工具。GoFrame旨在提供一套完整的开发工具和库,帮助开发者在企业级应用开发中提高效率,适合构建大型应用或微服务。

快速入门

快速入门这里完全是在gin官网搬进来的,win环境大致也是这样的流程

要求

  • Go 1.13 及以上版本

安装

要安装 Gin 软件包,需要先安装 Go 并设置 Go 工作区。

1.下载并安装 gin:

$ go get -u github.com/gin-gonic/gin

2.将 gin 引入到代码中:

import "github.com/gin-gonic/gin"

3.(可选)如果使用诸如 http.StatusOK 之类的常量,则需要引入 net/http 包:

import "net/http"
  1. 创建你的项目文件夹并 cd 进去
$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
  1. 拷贝一个初始模板到你的项目里
$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
  1. 运行你的项目
$ go run main.go

开始

不确定如何编写和执行 Go 代码? 点击这里.

首先,创建一个名为 example.go 的文件

$ touch example.go

接下来, 将如下的代码写入 example.go 中:

package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}

然后, 执行 go run example.go 命令来运行代码:

# 运行 example.go 并且在浏览器中访问 HOST_IP:8080/ping
$ go run example.go

示例

1. 查询字符串参数

查询字符串参数是URL的一部分,用于传递额外的信息给服务器。它们位于URL的?后面,格式为key=value,多个参数之间用&分隔。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default() // Default自动添加了两个中间件:Logger和Recovery,后面章节中还有详细的解释
    // 定义GET请求的处理函数,处理/search路径的请求
    r.GET("/search", func(c *gin.Context) {
        // 通过DefaultQuery方法获取名为"query"的查询参数的值,如果没有该参数,则默认为"none"
        query := c.DefaultQuery("query", "none")
        // 使用JSON方法返回查询结果,状态码为200
        c.JSON(200, gin.H{"result": query})
    })
    // 启动服务器,默认监听8080端口
    r.Run()
}
// http://localhost:8080/search?query=123

2. 路由参数

路由参数允许将变量嵌入到URL路径中,使得可以通过访问不同的URL路径来获取不同的资源。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    // 定义一个带参数的路由,:name是一个路由参数
    r.GET("/user/:name", func(c *gin.Context) {
        // 使用Param方法获取路由参数"name"的值
        name := c.Param("name")
        // 以JSON格式返回用户信息,状态码为200
        c.JSON(200, gin.H{"user": name})
    })
    r.Run() // 启动服务器
}
// http://localhost:8080/user/xiaoming

3. 使用HTTP方法

HTTP方法指的是HTTP协议中定义的方法,如GET、POST等,分别用于获取资源、提交资源等操作。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    // 处理GET请求
    r.GET("/get", func(c *gin.Context) {
        c.String(200, "GET request")
    })
    // 处理POST请求
    r.POST("/post", func(c *gin.Context) {
        c.String(200, "POST request")
    })
    r.Run() // 启动服务器
}
// http://localhost:8080/get

4. 静态文件服务

静态文件服务用于提供静态资源,如图片、CSS文件和JavaScript文件等。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    // 静态文件服务,将URL路径/assets映射到本地的./assets目录
    r.Static("/assets", "./assets")
    r.Run() // 启动服务器
}
// http://localhost:8080/assets/abc.js

5. 设置和获取Cookie

Cookie是服务器存储在用户浏览器上的小数据片段,常用于识别用户。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    r := gin.Default()
    r.GET("/cookie", func(c *gin.Context) {
        // 设置一个名为"gin_cookie"的Cookie,值为"test_value"
        c.SetCookie("gin_cookie", "test_value", 3600, "/", "localhost", false, true)
        // 尝试获取名为"gin_cookie"的Cookie值
        cookie, err := c.Cookie("gin_cookie")
        if err != nil {
            // 如果获取失败,返回错误信息
            c.JSON(http.StatusBadRequest, gin.H{"error": "No cookie found!"})
            return
        }
        // 如果获取成功,返回Cookie的值
        c.JSON(http.StatusOK, gin.H{"cookie": cookie})
    })
    r.Run() // 启动服务器
}
// http://localhost:8080/cookie 
// 第一次 No cookie found!
// http://localhost:8080/cookie
// 第二次 {"cookie":"test_value"}

6. HTML渲染

Gin支持直接渲染HTML模板,方便生成动态网页。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    // 加载模板文件
    r.LoadHTMLGlob("templates/*")
    r.GET("/index", func(c *gin.Context) {
    // 渲染模板,传递"title"变量
    c.HTML(200, "index.html", gin.H{
        "title": "主站",
    })
})

    r.Run() // 启动服务器
}

templates/index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"> <!-- 确保正确设置字符集 -->
    <title>{{.title}}</title>
</head>
<body>
    <h1>欢迎来到 {{.title}}</h1>
    <p>这是一个使用Gin与模板结合的简单示例。</p>
</body>
</html>

访问:http://localhost:8080/index

7. JSON/XML渲染

Gin提供了简单的方法来返回JSON或XML格式的响应,常用于构建API。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    // 返回JSON格式的响应
    r.GET("/json", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "hello", "status": 200})
    })
    // 返回XML格式的响应
    r.GET("/xml", func(c *gin.Context) {
        c.XML(200, gin.H{"message": "hello", "status": 200})
    })
    r.Run() // 启动服务器
}
// http://localhost:8080/json
// http://localhost:8080/xml

8. 只绑定URL查询字符串

Gin可以将URL查询字符串参数绑定到结构体,方便数据处理。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

type QueryInfo struct {
    Name    string `form:"name"`
    Address string `form:"address"`
}

func main() {
    r := gin.Default()
    r.GET("/query", func(c *gin.Context) {
        var queryInfo QueryInfo
        // 将请求中的查询字符串参数绑定到结构体
        if c.ShouldBindQuery(&queryInfo) == nil {
            // 绑定成功,以JSON格式返回数据
            c.JSON(200, gin.H{"name": queryInfo.Name, "address": queryInfo.Address})
        }
    })
    r.Run() // 启动服务器
}
// http://localhost:8080/query?name=盖伦&address=德玛西亚

9. Query和post form

处理URL查询参数和表单提交的数据,常用于处理GET和POST请求。

示例代码

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.POST("/form", func(c *gin.Context) {
        // 从表单中获取"type"和"name"字段的值
        typeStr := c.PostForm("type")
        name := c.PostForm("name")
        // 以JSON格式返回获取到的数据
        c.JSON(200, gin.H{"type": typeStr, "name": name})
    })
    r.Run() // 启动服务器
}
// 这个就不写了,自己用psotman试试去吧

综合示例

示例中包含如下内容:

  • 处理不同类型的HTTP请求(GET, POST)
  • 静态文件服务
  • Cookie的设置与获取
  • 模板渲染
  • JSON和XML格式的响应
  • 查询字符串和表单数据的绑定
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type QueryInfo struct {
	Name    string `form:"name"`
	Address string `form:"address"`
}

func main() {
	r := gin.Default()

	// 静态文件服务
	r.Static("/assets", "./assets")

	// 加载模板文件
	r.LoadHTMLGlob("templates/*")

	// 处理GET请求
	r.GET("/search", func(c *gin.Context) {
		query := c.DefaultQuery("query", "none")
		c.JSON(200, gin.H{"result": query})
	})

	r.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.JSON(200, gin.H{"user": name})
	})

	r.GET("/get", func(c *gin.Context) {
		c.String(200, "GET request")
	})

	r.GET("/index", func(c *gin.Context) {
		c.HTML(200, "index.html", gin.H{
			"title": "主站",
		})
	})

	r.GET("/json", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "hello", "status": 200})
	})

	r.GET("/xml", func(c *gin.Context) {
		c.XML(200, gin.H{"message": "hello", "status": 200})
	})

	r.GET("/query", func(c *gin.Context) {
		var queryInfo QueryInfo
		if c.ShouldBindQuery(&queryInfo) == nil {
			c.JSON(200, gin.H{"name": queryInfo.Name, "address": queryInfo.Address})
		}
	})

	r.GET("/cookie", func(c *gin.Context) {
		c.SetCookie("gin_cookie", "test_value", 3600, "/", "localhost", false, true)
		cookie, err := c.Cookie("gin_cookie")
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "No cookie found!"})
			return
		}
		c.JSON(http.StatusOK, gin.H{"cookie": cookie})
	})

	// 处理POST请求
	r.POST("/post", func(c *gin.Context) {
		c.String(200, "POST request")
	})

	r.POST("/form", func(c *gin.Context) {
		typeStr := c.PostForm("type")
		name := c.PostForm("name")
		c.JSON(200, gin.H{"type": typeStr, "name": name})
	})

	// 启动服务器,默认监听8080端口
	r.Run()
}

(未完待续……)