beego是一个快速开发go应用的http框架。beego可以用来快速开发API、web、后端服务等各种应用,是一个restful风格的框架,主要设计灵感来源于tornado、sinatra、flask这三个框架,但是结合了go本身的一些特性(interface、struct以及继承等)而设计的一个框架。
Iris是一个快速,简单但功能齐全的非常有效率的web框架,提供了一个优美的表现力和容易使用的网站或API的基础。
作为初学者很多时候,在学习一个框架的时候,一定要搞清楚为什么要学习它,这个非常的重要。
gin框架:使用的人多,大家都在用,所以就得学
随着互联网技术的发展,在早期我们大部分情况下,编写的都是静态网页html,如果有100篇文章就要编写100篇与之对应的静态网页,这样是非常痛苦的。于是乎就开始有了动态网页,动态网页必须要结合服务器端的技术,比如:go、java等。有了这些服务端语言的加持这样就可以完成一个静态网页到动态网页的转化。如下图:
新建go.mod文件,有两种方案
go mod init
即可下载gin:在终端中输入命令:go get -u github.com/gin-gonic/gin
创建demo.go,输入代码:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
// 创建一个gin服务
ginServer := gin.Default()
// 发起请求
ginServer.GET("/hello", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "hello gin",
})
})
// 设置端口,启动服务
ginServer.Run(":8088")
}
restfu:用url定位资源,用HTTP动词(get、post、put、delete)描述操作。
restful api就是rest风格的api,即rest是一种架构风格,跟编程语言无关,跟平台无关,采用http做传输协议。
简单来说,rest的含义就是客户端与web服务器之间进行交互时,使用http协议中的4个请求方法代表不同的动作。
get
:用来获取资源post
:用来新建资源put
:用来更新资源delete
:用来删除资源只要api程序遵循了rest风格,那就可以称其为restful api。目前在前后端分离的架构中,前后端基本都是采用restful api来进行交互。
以前的写法
get /user
post /create_user
post /update_user
post /delete_user
restful写法
get /user
post /user
put /user
delete /user
gin框架支持restful api
ginServer.GET("/user", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "GET",
})
})
ginServer.POST("/user", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "POST",
})
})
ginServer.PUT("/user", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "PUT",
})
})
ginServer.DELETE("/user", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "DELETE",
})
})
测试其它请求使用postman进行测试
gin服务如何跳转到html页面
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Go Gin框架title>
head>
<body>
<h1>我是首页h1>
{{.msg}}
body>
html>
// 加载静态网页
ginServer.LoadHTMLGlob("templates/*")
ginServer.GET("/index", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK,"index.html",gin.H{
"msg":"hello 我是一条msg",
})
})
index页面如要要渲染请求中数据,使用{{.}}进行渲染
例如请求中,gin.H{"msg":"hello 我是一条msg",}
map数据,页面使用{{.msg}}进行渲染
如果要加载css、js等静态资源,将文件保存在static目录下
// 加载静态资源
ginServer.Static("/static", "./static")
gin.H{}
,它本质就是一个maptype H map[string]any
// gin.H{}本质就是一个map
ginServer.GET("/json1", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"name": "zhangsan",
"age": 18,
})
})
/models/User.go
package models
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Sex string `json:"sex"`
}
// 结构体User
ginServer.GET("/json2", func(ctx *gin.Context) {
user := models.User{
Name: "zhangsan",
Age: 18,
Sex: "男",
}
ctx.JSON(http.StatusOK, user)
})
// 结构体切片
ginServer.GET("/json2", func(ctx *gin.Context) {
users:=make([]models.User,2)
users[0] = models.User{"zhangsan1",18,"男"}
users[1] = models.User{"lisi",18,"女"}
ctx.JSON(http.StatusOK, users)
})
query参数为url路径中?后以key=value形式存储的数据
例如请求路径:https://localhost:8088/user/info?userId=1&name=zhangsan
// query参数
// http://localhost:8088/user/info?userId=1&name=zhangsan
ginServer.POST("/user/info", func(ctx *gin.Context) {
userId := ctx.Query("userId")
name := ctx.Query("name")
ctx.JSON(http.StatusOK, gin.H{
"userId": userId,
"name": name,
})
})
param参数为restful风格的url的参数
例如url:https://localhost:8088/user/info/1/zhangsan
// param参数
// https://localhost:8088/user/info/1/zhangsan
ginServer.POST("/user/info/:userId/:name", func(ctx *gin.Context) {
userId := ctx.Param("userId")
name := ctx.Param("name")
ctx.JSON(http.StatusOK, gin.H{
"userId": userId,
"name": name,
})
})
// 表单参数
ginServer.POST("/user/form", func(ctx *gin.Context) {
username := ctx.PostForm("username")
password := ctx.PostForm("password")
ctx.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
})
})
// json数据 GetRawData()获取
ginServer.POST("/user/json", func(ctx *gin.Context) {
// 获取json字符串,类型为byte
userData, _ := ctx.GetRawData()
user := map[string]any{}
// byte转map
json.Unmarshal(userData, &user)
ctx.JSON(http.StatusOK, user)
})
// http重定向
ginServer.GET("/redirect", func(ctx *gin.Context) {
ctx.Redirect(http.StatusFound, "https://www.baidu.com")
})
注意:如果要重定向到站外地址,必须要写完整地址,例如https://www.baidu.com
不能省略https
否则就会与自己主机地址进行拼接,例如如果写成:www.baidu.com
,最后访问路径就是http://localhost:8088/www.baidu.com
ginServer.NoRoute(func(ctx *gin.Context) {
ctx.HTML(http.StatusNotFound, "404.html", gin.H{
"err": "你的页面找不到了",
})
})
在业务架构,我们通常会把一类相同类型的业务采用相同的前缀名字以便和其它类型的业务区分开,方便开发人员维护和设计。
例如,有关用户的一类业务,接口都是/user/* ,订单的一类业务,接口为/order/*
在gin框架中,我们可以把这一统一的前缀提取出来,定义为一个路由组,方便区分,代码也会更简介。
// 订单业务
orderGroup:=ginServer.Group("/order")
orderGroup.GET("/list", func(ctx *gin.Context) { })
orderGroup.GET("/update", func(ctx *gin.Context) { })
orderGroup.GET("/add", func(ctx *gin.Context) { })
orderGroup.GET("/delete", func(ctx *gin.Context) { })
访问的真实接口就是:
/order/list
/order/update
/order/add
/order/delete
gin框架允许开发者在处理请求时,加入用户自己设计的函数。
它用于处理一些公共的业务逻辑。例如登录认证、权限校验、数据分页、记录日志、耗时统计等。
也就是我们所说的中间件。
必须是一个gin.HanderFunc
类型。
func MyHandler() gin.HandlerFunc {
return func(ctx *gin.Context) {
fmt.Println("请求 ----- start")
if true {
// 请求继续向下执行
ctx.Next()
} else {
// 中断
ctx.Abort()
}
fmt.Println("请求 ----- end")
}
}
ginServer.Use(MyHandler())
注意:注册中间件一定要定义在所有请求的前面
如果只想在一类业务或某一个请求上加入中间件,gin框架同样可以做到。
在路由组中加入中间件:
orderGroup:=ginServer.Group("/order", MyHandler())
orderGroup.GET("/list", func(ctx *gin.Context) { })
orderGroup.GET("/update", func(ctx *gin.Context) { })
orderGroup.GET("/add", func(ctx *gin.Context) { })
orderGroup.GET("/delete", func(ctx *gin.Context) { })
在某一个请求上加入中间件,中间件作为参数定义在请求接口后,真正的请求之前
ginServer.GET("/user", MyHandler() ,func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "GET",
})
})
gin.Default()
默认使用了Logger
和Recovery
中间件
Logger
中间件将日志写入gin.DefaultWriter
,即配置了GIN_MODE = release
。
Recovery
中间件会recover任何panic。如果有panic,会写入500响应码。
如果不想使用上面两个默认的中间件,可以使用gin.New()
新建一个gin服务。
在定义中间件时可以存储数据,这个数据可以在定义了中间件的任何请求中获取到:
中间件:
func MyHandler() gin.HandlerFunc {
return func(ctx *gin.Context) {
ctx.Set("name","zhangsan")
ctx.Next()
}
}
请求:
ginServer.GET("/user", MyHandler() ,func(ctx *gin.Context) {
name,ok:=ctx.Get("name")
if !ok {
name = "unknown"
}
ctx.JSON(http.StatusOK, gin.H{
"msg": "GET",
"name" : name,
})
})
session的使用:
导入session的源码
go get github.com/gin-contrib/sessions
package models
type User struct {
Id int64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
Sex string `json:"sex"`
}
// 创建一个gin服务
ginServer := gin.Default()
// 创建cookie存储
store:=cookie.NewStore([]byte("mycookie"))
// 添加session中间件
ginServer.Use(sessions.Sessions("mysession", store))
// 注册用户模型
gob.Register(models.User{})
// 登录添加session
ginServer.POST("/login", func(ctx *gin.Context) {
// 创建一个session
session:=sessions.Default(ctx)
// 将用户放入session中
session.Set("user",models.User{
Id: 1,
Name: "zhangsan",
Age: 18,
Sex: "男",
})
// 保存
session.Save()
})
ginServer.POST("/session", func(ctx *gin.Context) {
session:=sessions.Default(ctx)
// 获取session中信息
user:=session.Get("user")
ctx.JSON(http.StatusOK,user)
})
// 设置端口,启动服务
ginServer.Run(":8088")