【Gin】初识Gin框架,模板基本语法

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 1.Gin介绍Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧


1.Gin介绍


Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧


下载gin:


go get -u github.com/gin-gonic/gin


将gin引入到代码中:


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


2.第一个gin网站


示例


以下展示一个最小的gin web程序


package main
import (
  "github.com/gin-gonic/gin"
)
// hello 路径的函数
func sayHello(c *gin.Context) {
  c.JSON(200, gin.H{
    "message": "hello gin!",
  }) // 返回一个JSON数据
}
func main() {
  r := gin.Default() // 返回默认的路由引擎
  // 指定用户使用GET请求访问/hello时,执行sayHello函数
  r.GET("hello/", sayHello)
  // 启动服务
  r.Run()
}


启动程序之后,浏览器访问:


http://127.0.0.1:8080/hello/


输出信息:


{"message":"hello gin!"}


RESTful API


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

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

GET用来获取资源POST用来新建资源PUT用来更新资源DELETE用来删除资源。只要API程序遵循了REST风格,那就可以称其为RESTful API。目前在前后端分离的架构中,前后端基本都是通过RESTful API来进行交互。

例如,我们现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作,我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。按照经验我们通常会设计成如下模式:




同样的需求我们按照RESTful API设计如下:




开发RESTful API的时候我们通常使用Postman来作为客户端的测试工具🥖

代码:


package main
import (
  "github.com/gin-gonic/gin"
)
func main() {
  r := gin.Default() // 返回默认的路由引擎
  // 指定用户使用GET请求访问/hello时,执行函数
  r.GET("hello/", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "method": "GET",
    })
  })
  // RESTful风格 API
  r.POST("hello/", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "method": "POST",
    })
  })
  r.PUT("hello/", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "method": "PUT",
    })
  })
  r.DELETE("hello/", func(c *gin.Context) {
    c.JSON(200, gin.H{
      "method": "DELETE",
    })
  })
  // 启动服务
  r.Run()
}


3.模板渲染


html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用html/template这个包


模板与渲染


在一些前后端不分离的Web架构中,我们通常需要在后端将一些数据渲染到HTML文档中,从而实现动态的网页(网页的布局和样式大致一样,但展示的内容并不一样)效果。

我们这里说的模板可以理解为事先定义好的HTML文档文件,模板渲染的作用机制可以简单理解为文本替换操作–使用相应的数据去替换HTML文档中事先准备好的标记。


很多编程语言的Web框架中都使用各种模板引擎,比如Python语言中Flask框架中使用的jinja2模板引擎。


Go语言的模板引擎


Go语言内置了文本模板引擎text/template和用于HTML文档的html/template。它们的作用机制可以简单归纳如下:


模板文件通常定义为.tmpl和.tpl为后缀(也可以使用其他的后缀),必须使用UTF8编码。

模板文件中使用{{和}}包裹和标识需要传入的数据。

传给模板这样的数据就可以通过点号(.)来访问,如果数据是复杂类型的数据,可以通过{{ .FieldName }}来访问它的字段。

除{{和}}包裹的内容外,其他内容均不做修改原样输出。


模板引擎的使用


创建的模板文件:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>hint</title>
</head>
<body>
<h1>Hello {{ . }}</h1>
</body>
</html>


解析模板:


// 解析模板
// 当前路径下的tmpl
t, err := template.ParseFiles("./tem.tmpl")
if err != nil {
  fmt.Println("ParseFiles failed error:%v", err)
  return
}


渲染模板:


// 渲染模板
err = t.Execute(w, "大河之犬")
if err != nil {
  fmt.Println("tmpl Execute failed err=%v", err)
}


后端文件:


package main
import (
  "fmt"
  "html/template"
  "net/http"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
  // 解析模板
  // 当前路径下的tmpl
  t, err := template.ParseFiles("./tem.tmpl")
  if err != nil {
    fmt.Println("ParseFiles failed error:%v", err)
    return
  }
  // 渲染模板
  err = t.Execute(w, "大河之犬")
  if err != nil {
    fmt.Println("tmpl Execute failed err=%v", err)
  }
}
func main() {
  // http服务
  http.HandleFunc("/", sayHello)
  // 使用9000端口
  err := http.ListenAndServe(":9000", nil)
  if err != nil {
    fmt.Println("HTTP server start failed , err %v", err)
    return
  }
}


打开浏览器,可成功渲染:



4.模板语法


模板渲染结构体


type User struct {
  Name string
  Sex  string
  Age  int
}
func sayHello(w http.ResponseWriter, r *http.Request) {
  // 解析模板
  // 当前路径下的tmpl
  t, err := template.ParseFiles("./tem.tmpl")
  if err != nil {
    fmt.Println("ParseFiles failed error:%v", err)
    return
  }
  // 渲染模板
  u1 := User{
    Name: "dahe", // 别人可以访问时,首字母要大写
    Sex:  "男",
    Age:  18,
  }
  err = t.Execute(w, u1)
  if err != nil {
    fmt.Println("tmpl Execute failed err=%v", err)
  }
}


模板文件:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>hint</title>
</head>
<body>
<h1>Hello {{ .Name }}</h1>
<h1>Sex {{ .Sex }}</h1>
<h1>Age {{ .Age }}</h1>
</body>
</html>


同样的,模板渲染map:


func sayHello(w http.ResponseWriter, r *http.Request) {
  // 解析模板
  // 当前路径下的tmpl
  t, err := template.ParseFiles("./tem.tmpl")
  if err != nil {
    fmt.Println("ParseFiles failed error:%v", err)
    return
  }
  // 渲染模板
  m1 := map[string]interface{}{
    "Name": "dahe", // map无需首字母大写
    "Sex":  "女",
    "Age":  "20",
  }
  err = t.Execute(w, m1)
  if err != nil {
    fmt.Println("tmpl Execute failed err=%v", err)
  }
}


模板传递多个参数


func sayHello(w http.ResponseWriter, r *http.Request) {
  // 解析模板
  // 当前路径下的tmpl
  t, err := template.ParseFiles("./tem.tmpl")
  if err != nil {
    fmt.Println("ParseFiles failed error:%v", err)
    return
  }
  // 渲染模板
  u1 := User{
    Name: "wangwei",
    Sex:  "男",
    Age:  18,
  }
  m1 := map[string]interface{}{
    "Name": "dahe", // map无需首字母大写
    "Sex":  "女",
    "Age":  "20",
  }
  err = t.Execute(w, map[string]interface{}{
    "u1": u1,
    "m1": m1,
  })
  if err != nil {
    fmt.Println("tmpl Execute failed err=%v", err)
  }
}


模板文件:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>hint</title>
</head>
<body>
<h1>Hello {{ .u1.Name }}</h1>
<h1>Sex {{ .u1.Sex }}</h1>
<h1>Age {{ .u1.Age }}</h1>
<h1>Hello {{ .m1.Name }}</h1>
<h1>Sex {{ .m1.Sex }}</h1>
<h1>Age {{ .m1.Age }}</h1>
</body>
</html>


成功渲染:



注释


{{/* a comment */}}
注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。


变量


{{ $hello := "ai" }}
{{ $tempSex := .m1.Sex }}
{{ $hello }}
{{ $tempSex }}


移除空格


有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,这个时候可以使用{{-语法去除模板内容左侧的所有空白符号, 使用-}}去除模板内容右侧的所有空白符号。


{{- .Name -}}


条件判断


Go模板语法中的条件判断有以下几种:


{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}


例如:


{{ if eq .m1.Name "dahe" }}
  <h2>你好啊,dahe</h2>
{{ end }}


比较函数


布尔函数会将任何类型的零值视为假,其余视为真。

下面是定义为函数的二元比较运算的集合:


eq      如果arg1 == arg2则返回真
ne      如果arg1 != arg2则返回真
lt      如果arg1 < arg2则返回真
le      如果arg1 <= arg2则返回真
gt      如果arg1 > arg2则返回真
ge      如果arg1 >= arg2则返回真


为了简化多参数相等检测,eq(只有eq)可以接受2个或更多个参数,它会将第一个参数和其余参数依次比较,返回下式的结果:


{{eq arg1 arg2 arg3}}


range


我们在后端传入一个切片:


hobbyList := []string{
  "C++",
  "Java",
  "Go",
}
m1 := map[string]interface{}{
  "Name":  "dahe", // map无需首字母大写
  "Sex":   "女",
  "Age":   "20",
  "Hobby": hobbyList,
}


模板使用range进行渲染:


{{ range $idx,$hobby := .m1.Hobby }}
    <p>{{$idx}} - {{$hobby}}</p>
{{ end }}



range-else:


{{ range $idx,$hobby := .m1.Hobby }}
    <p>{{$idx}} - {{$hobby}}</p>
{{else}}
    没有爱好
{{ end }}


index取值:


{{with .m1}}
    <p>{{ index .Hobby 2 }}</p>
    <!--取第三个元素-->
{{end}}


with


简化模板语言变量的使用,例如,局部使用.m1值


{{with .m1}}
    <p>{{.Name}}</p>
    <p>{{.Age}}</p>
{{end}}
目录
相关文章
|
6月前
|
JSON 中间件 API
Gin框架笔记(一) Gin框架的安装与Hello World
Gin框架笔记(一) Gin框架的安装与Hello World
229 0
|
6月前
|
JSON 中间件 数据格式
Gin框架学习笔记(六)——gin中的日志使用
Gin框架学习笔记(六)——gin中的日志使用
250 0
|
6月前
|
JSON 前端开发 Java
|
6月前
|
前端开发 中间件 关系型数据库
|
7月前
|
XML JSON 人工智能
探索Gin框架:Golang Gin框架请求参数的获取
探索Gin框架:Golang Gin框架请求参数的获取
|
JSON 中间件 数据库连接
gin 框架中的 gin.Context
Context 是 gin 中最重要的部分。 例如,它允许我们在中间件之间传递变量、管理流程、验证请求的 JSON 并呈现 JSON 响应。Context 中封装了原生的 Go HTTP 请求和响应对象,同时还提供了一些方法,用于获取请求和响应的信息、设置响应头、设置响应状态码等操作。
692 0
gin 框架中的 gin.Context
|
前端开发 JavaScript Go
【Gin】模板的高级用法
这样我们只需要在模板文件不需要转义的内容后面使用我们定义好的safe函数就可以了。 {{ . | safe }}
396 1
【Gin】模板的高级用法
|
Go API
gin框架学习-快速安装gin
Gin 是一个用 Go (Golang) 编写的 Web 框架,由于 httprouter,它具有 martini 的 API,性能提高了 40 倍。具有高性能的优点。
165 0
gin框架学习-快速安装gin
|
开发工具
基于Gin封装Web框架 - 3. 初始化 rum 框架
基于Gin封装Web框架 - 3. 初始化 rum 框架
192 0
基于Gin封装Web框架 - 3. 初始化 rum 框架
|
Go PHP
Gin从入门到精通—如何理解安装Gin并在本地运行
Gin从入门到精通—如何理解安装Gin并在本地运行
518 0
Gin从入门到精通—如何理解安装Gin并在本地运行