详细的学习gin的知识点,不是第一次学习了,这次梳理一个学习的文档出来
第一个gin程序
这里我们开始演示一下gin的开始程序,也就是快速入门。
我们来看一下代码:
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 mod进行包的导入
代码细节
第一行代码
r := gin.Default()
这个一行代码,就是产生了一个gin的实例
然后后面进行操作,
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
这里面首先有一个GET方法,对于这个GET方法我们首先来看一下它的源码
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
看到源码我们可以看到里面的参数,首先第一个参数就是注册的路径,然后第二个就是处理器的注册。
在这里我们注册的是一个匿名函数。当然我们也可以修改成:
func pong(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
}
func main() {
r := gin.Default()
r.GET("/ping", pong)
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
在这里我们需要注意的就是这个函数的类型要是:func (c *gin.Context)
然后我们可以发现在传递参数的里面,我们使用的是gin.H
我们点开它的源码:
// H is a shortcut for map[string]interface{}
type H map[string]interface{}
我们看到了它就是一个map类型,因为在gin中经常使用的原因,所以开发者对它进行了封装。这样我们使用起来就更加的方便。
gin中new和Default的不同
在这里我们介绍两个方法,他们返回回来的都是一个*Engine
那么它们有什么不一样呢,在这里我们要知道的是不一样的点是使用Default后它会默认开启两个中间件,一个是recover一个是logger。
路由分组和URL
在我们的开发中,我们为了程序的可读性,我们一般会把路由进行分组。
也是为了后期更好的寻找路由。
那么我们如何进行分组呢?
我们使用的是Group方法。
package main
import "github.com/gin-gonic/gin"
func pong(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
}
//演示分组
func main() {
r := gin.Default()
group := r.Group("/v1")
{
group.GET("/ping", pong)
}
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
获取url参数
这里我们通过url传入参数,那么我们怎么操作呢?
package main
import "github.com/gin-gonic/gin"
func pong(c *gin.Context) {
id := c.Param("id")
c.JSON(200, gin.H{
"message": id,
})
}
//演示分组
func main() {
r := gin.Default()
group := r.Group("/v1")
{
group.GET("/:id", pong)
}
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
但是呢我们可以发现这个东西是有问题的,我们这里设定的是id,按照我们常识这里,我们知道id一般来说是数字,但是这里不管是数值还是什么都可以传输。
那么我们怎么进行限制呢?
这里我们运用到了之后的表单验证的方式。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
type Person struct {
ID string `uri:"id" binding:"required,uuid"`
Name string `uri:"name" binding:"required"`
}
func main() {
r := gin.Default()
r.GET("/:name/:id", func(context *gin.Context) {
var person Person
if err := context.ShouldBindUri(&person);err != nil{
context.Status(404)
return
}
context.JSON(http.StatusOK,gin.H{
"name":person.Name,
"id":person.ID,
})
})
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
获取GET和POST参数
这两种方式是我们比较常见的方式。那么下面我们详细的说明一下
GET
使用到的方法有两个一个是DefaultQuery和Query。这两个方法的区别在于,前者是可以有默认值的,后者不能设置默认值
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/name",name)
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
func name(c *gin.Context){
name := c.DefaultQuery("name","lzz")
c.JSON(http.StatusOK,gin.H{
"name":name,
})
}
POST
在post中我们要取出参数,我们也有两个方法,两个方法的区别和上面是一样的。
分别是DefaultPostForm和PostForm。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.POST("/postname",Postname)
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
func Postname(c *gin.Context) {
posrname := c.DefaultPostForm("name","lzz")
c.JSON(http.StatusOK,gin.H{
"name":posrname,
})
}
关于gin表单验证
我们在做web开发的时候,肯定是会遇见表单验证的需求的,表单验证也是为了一定的安全性。
关于表单验证这里我们直接上代码,详情可以查看官方文档。
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
type LoginForm struct {
User string `form:"user1" json:"user" binding:"required,min=3,max=10"`
Password string `form:"password" json:"password" binding:"required"`
}
type SignUpForm struct {
Age uint8 `form:"age" json:"age" binding:"gte=1,lte=130"`
Name string `form:"name" binding:"required,min=3"`
Email string `form:"email" binding:"required,email"`
Password string `form:"password" binding:"required"`
RePassword string `form:"re_password" binding:"required,eqfield=Password"`
}
func main() {
router := gin.Default()
router.POST("/login", func(c *gin.Context) {
var login LoginForm
if err := c.ShouldBind(&login);err != nil{
fmt.Println(err.Error())
c.JSON(http.StatusBadRequest,gin.H{
"err": err.Error(),
})
return
}
c.JSON(http.StatusOK,gin.H{
"msg":"登录成功",
})
})
router.POST("/sigin", func(context *gin.Context) {
var siginUpForm SignUpForm
if err := context.ShouldBind(&siginUpForm); err != nil{
fmt.Println(err.Error())
context.JSON(http.StatusBadRequest,gin.H{
"err":err.Error(),
})
return
}
context.JSON(http.StatusOK,gin.H{
"msg":"成功",
})
})
router.Run()
}