写在前面
基本上是在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"
- 创建你的项目文件夹并
cd进去
$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
- 拷贝一个初始模板到你的项目里
$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
- 运行你的项目
$ 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()
}
(未完待续……)