GO常用web框架之gin学习笔记(1)| 青训营笔记

353 阅读4分钟

[ go 与 golang | 青训营笔记]

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天, 在学习了go的相关基础知识以后,可以说是初步的了解了go,接下来,我们将步入全新的环节,今天我们学习go的一个常用web框架gin

1. gin之hello world

Gin在GitHub上已经有47k的star,它和Golang的语法一样简洁明了,使得初学者得以迅速入门。

安装

命令行输入
go get -u github.com/gin-gonic/gin

hello world

使用gin编写一个接口也是非常简单

package main

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

func main() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello World")
    })
    router.Run(":8000") 
}
  1. router:=gin.Default():这是默认的服务器。使用gin的Default方法创建一个路由Handler
  2. 然后通过Http方法绑定路由规则和路由函数。不同于net/http库的路由函数,gin进行了封装,把requestresponse都封装到了gin.Context的上下文环境中。
  3. 最后启动路由的Run方法监听端口。还可以用http.ListenAndServe(":8080", router),或者自定义Http服务器配置。

两种启动方式

// 启动方式一
router.Run(":8000")
// 启动方式二
http.ListenAndServe(":8000", router)

修改ip为内网ip

router.Run("0.0.0.0:8000")
package main

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

func Index(context *gin.Context) {
  context.String(200, "Hello zhaoran!")
}
func main() {

  // 创建一个默认的路由
  router := gin.Default()

  // 绑定路由规则和路由函数,访问/index的路由,将由对应的函数去处理
  router.GET("/index", Index)

  // 启动监听,gin会把web服务运行在本机的0.0.0.0:8080端口上
  router.Run("0.0.0.0:8080")
  // 用原生http服务的方式, router.Run本质就是http.ListenAndServe的进一步封装
  http.ListenAndServe(":8080", router)
}

2. 响应码概述

状态码

200 表示正常响应 http.StatusOK

响应

返回字符串

router.GET("/index", func(c *gin.Context) {
  c.String(http.StatusOK, "hello world")
})

返回json

router.GET("/json", func(c *gin.Context) {
  c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
// 结构体转json
router.GET("/moreJSON", func(c *gin.Context) {
  // You also can use a struct
  type Msg struct {
    Name    string `json:"user"`
    Message string
    Number  int
  }
  msg := Msg{"fengfeng", "hey", 21}
  // 注意 msg.Name 变成了 "user" 字段
  // 以下方式都会输出 :   {"user": "hanru", "Message": "hey", "Number": 123}
  c.JSON(http.StatusOK, msg)
})

返回xml

router.GET("/xml", func(c *gin.Context) {
  c.XML(http.StatusOK, gin.H{"user": "hanru", "message": "hey", "status": http.StatusOK})
})

返回yaml

router.GET("/yaml", func(c *gin.Context) {
  c.YAML(http.StatusOK, gin.H{"user": "hanru", "message": "hey", "status": http.StatusOK})
})

返回html

先要使用 LoadHTMLGlob()或者LoadHTMLFiles()方法来加载模板文件

//加载模板
router.LoadHTMLGlob("gin框架/templates/*")
//router.LoadHTMLFiles("templates/index.html", "templates/index2.html")
//定义路由
router.GET("/html", func(c *gin.Context) {
  //根据完整文件名渲染模板,并传递参数
  c.HTML(http.StatusOK, "index.html", gin.H{
    "title": "hello world",
  })
})

在模板中使用这个title,需要使用{{ .title }}

不同文件夹下模板名字可以相同,此时需要 LoadHTMLGlob() 加载两层模板路径。

router.LoadHTMLGlob("templates/**/*")
router.GET("/posts/index", func(c *gin.Context) {
    c.HTML(http.StatusOK, "posts/index.html", gin.H{
        "title": "Posts",
    })
    c.HTML(http.StatusOK, "users/index.html", gin.H{
        "title": "Users",
    })

})

文件响应

// 在golang总,没有相对文件的路径,它只有相对项目的路径
// 网页请求这个静态目录的前缀, 第二个参数是一个目录,注意,前缀不要重复
router.StaticFS("/static", http.Dir("static/static"))
// 配置单个文件, 网页请求的路由,文件的路径
router.StaticFile("/titian.png", "static/titian.png")

重定向

router.GET("/redirect", func(c *gin.Context) {
    //支持内部和外部的重定向
    c.Redirect(http.StatusMovedPermanently, "https://www.baidu.com/")
})

301 Moved Permanently

被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。

302 Found

请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。

3. 请求方式

RESTful API介绍

REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。

简单来说,REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作。

GET用来获取资源

POST用来新建资源

PUT用来更新资源

DELETE用来删除资源。

请求参数

查询参数 Query

func _query(c *gin.Context) {
  fmt.Println(c.Query("user"))
  fmt.Println(c.GetQuery("user"))
  fmt.Println(c.QueryArray("user")) // 拿到多个相同的查询参数
  fmt.Println(c.DefaultQuery("addr", "内蒙古"))
}

动态参数 Param

func _param(c *gin.Context) {
  fmt.Println(c.Param("user_id"))
  fmt.Println(c.Param("book_id"))
}


router.GET("/param/:user_id/", _param)
router.GET("/param/:user_id/:book_id", _param)

// ?param/12
// ?param/12/123

表单 PostForm

可以接收 multipart/form-data; application/x-www-form-urlencoded

func _form(c *gin.Context) {
  fmt.Println(c.PostForm("name"))
  fmt.Println(c.PostFormArray("name"))
  fmt.Println(c.DefaultPostForm("addr", "内蒙古")) // 如果用户没传,就使用默认值
  forms, err := c.MultipartForm()        // 接收所有的form参数,包括文件
  fmt.Println(forms, err)
}