初识Gin框架 | 青训营笔记

146 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

一、总览

  • Gin框架介绍
  • Gin框架的安装和使用
    • 安装
    • 第一个Gin实例程序
  • RESTful API
  • Gin 渲染

二、知识点详解

2.1 Gin框架介绍

Gin是一个用 Go (Golang) 编写的 web 框架。它是一个类似于martini但性能更好的API框架,不同于谢大主导的Beegoweb框架,后者更像是Python语言中的Django框架,内部包含了开发一个web程序所需的各种组件。

如果你是性能和高效的追求者,我相信你会像我一样爱上Gin。

2.2 Gin框架的安装和使用

  • 安装

下载并安装Gin:

go get -u github.com/gin-gonic/gin
  • 第一个Gin示例程序:
package main

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

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// GET:请求方式;/hello:请求的路径
	// 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数
	r.GET("/hello", func(c *gin.Context) {
		// c.JSON:返回JSON格式的数据
		c.JSON(200, gin.H{
			"message": "Hello world!",
		})
	})
	// 启动HTTP服务,默认在0.0.0.0:8080启动服务
	r.Run()
}

将以上代码保存在本地编译运行,可以使用浏览器打开127.0.0.1:8080/hello查看结果,可以看到返回的JSON字符串

2.3 RESTful API

REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。RESTful代表一种软件架构风格,即Representational State Transfer的缩写,中文名为”表现层状态转化“。

简单来说,REST可以理解为客户端与服务器进行交互时,使用HTTP协议中的4个不同的请求方法代表4中不同类型的状态转移类型,即:

  • GET用来获取资源

  • POST用来新建资源

  • PUT用来更新资源

  • DELETE用来删除资源

    只要API程序的设计遵循REST风格,那就可以称为RESTful API,同时Gin框架支持RESTful API的开发,考虑这个场景,客户需要我们编写一个管理书籍的系统,我们可以对一本书进行查询GET,创建POST,更新PUT和删除DELETE,在编写程序时我们需要设计客户访问路由与服务器交互时,服务器应该采取什么样的动作:

func main() {
	r := gin.Default()
	r.GET("/book", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "GET",
		})
	})

	r.POST("/book", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "POST",
		})
	})

	r.PUT("/book", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "PUT",
		})
	})

	r.DELETE("/book", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "DELETE",
		})
	})
}

这里对应不同的请求只是返回内容不同的JSON字符串,真正的业务逻辑要比这复杂的多。要想对服务器发送不同类型的请求需要用到PostmanPostman作为客户端的测试工具非常便利。

2.4 Gin 渲染

Gin 渲染模板一般分三步:定义模板、解析模板和渲染模板,假设我们定义了这样一个结构体:

type Usr struct {
   Name   string
   Gender string
   Age    int
   Hobby  []string
}

现在需要将用户的姓名、性别、年龄和兴趣爱好通过网页展示出来,首先定义一个简易的模板hello.tmpl:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello</title>
</head>
<body>
    <p>Hello {{.Name}}</p>
    <p>性别:{{.Gender}}</p>
    <p>年龄:{{.Age}}</p>
    <p>爱好是:</p>
<hr>
    {{ range $k, $hobby := .Hobby }}
        <p> {{$hobby}} </p>
    {{ else }}
        <p>没啥爱好</p>
    {{ end }}
</body>
</html>

其中{{.}}代表需要渲染的对象,如果传入的是结构体或其他复合数据类型,可以在.加上字段直接访问该对象的成员,然后解析模板,一般使用函数template.ParseFiles

// 2.解析模板
t, err := template.ParseFiles("C:\Users\周俊宇\GolandProjects\gin_demo\templateDemo\hello.tmpl")
if err != nil {
   fmt.Println("ParseFiles failed! ", err)
   return
}

最后是渲染模板:

// 3.渲染模板
var user = Usr{
   Name:   "小王子",
   Gender: "男",
   Age:    18,
   Hobby:  []string{"打篮球", "打排球", "打游戏"},
}
err = t.Execute(w, user)
if err != nil {
   fmt.Println("render template failed! ", err)
   return
}

完整代码:

package templateDemo

import (
   "fmt"
   "net/http"
   "text/template"
)

type Usr struct {
   Name   string
   Gender string
   Age    int
   Hobby  []string
}

func sayHello(w http.ResponseWriter, r *http.Request) {
   // 1.定义模板
   // 即 hello.tmpl
   // 2.解析模板
   t, err := template.ParseFiles("C:\Users\周俊宇\GolandProjects\gin_demo\templateDemo\hello.tmpl")
   if err != nil {
      fmt.Println("ParseFiles failed! ", err)
      return
   }
   // 3.渲染模板
   var user = Usr{
      Name:   "小王子",
      Gender: "男",
      Age:    18,
      Hobby:  []string{"打篮球", "打排球", "打游戏"},
   }
   err = t.Execute(w, user)
   if err != nil {
      fmt.Println("render template failed! ", err)
      return
   }
}

func TemplateDemo() {
   http.HandleFunc("/", sayHello)
   err := http.ListenAndServe(":9090", nil)
   if err != nil {
      fmt.Println("Http server starts failed!", err)
      return
   }
}

结果展示:

image.png