轻量级Web框架Gin开坑教程(一) | 掘金

开坑第一问

What is Gin?

官网介绍:Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 httprouter,速度提高了 40 倍。 如果您需要性能和良好的生产力,您一定会喜欢 Gin。

Gin为什么那么好用呢?这与它背后无数开源大佬有关,作为插件式web框架,背后有着一个开源小生态给Gin提供大量的插件。本文也在这里浅谈一下自己在学习中的一些见解,希望对各位有所帮助。

Hello Word

以下简单10行代码,即可打开一个web服务。

go 复制代码
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 上启动服务
}

其中gin.H的另一名称为map[string]interface{},该类型使用频繁,Gin使用另一名称代替。 以上代码是不是有些难懂,那么好!上正菜。

gin.Engine

老友们可能疑惑汉叁老哥这案例里gin.Default,是个什么东东?那你看到标题没,肯定和Engine有关系啊。你在用你绝顶的智慧在意推理。。。答案呼之欲出,这不就是返回来一个Engine对象吗。既然都已经知道这些了,那接下来的解释就方便多了。

Engine是什么?引擎。顾名思义这是Gin中极为核心的东西,Engine 是 Gin 框架最重要的数据结构,它是框架的入口。我们通过 Engine 对象来定义服务路由信息、组装插件、运行服务。正如 Engine 的中文意思「引擎」一样,它就是框架的核心发动机,整个 Web 服务的都是由它来驱动的。

区别于现实世界中的引擎,Engine如同一个简单的包装箱,引擎底层的HTTP服务器是使用Go语言中内置的http server,Engine实为对此的封装,所以它用起来方便快捷。

gin.Default() 函数会生成一个默认的 Engine 对象,里面包含了 2 个默认的常用插件,分别是 Logger 和 Recovery,Logger 用于输出请求日志,Recovery 确保单个请求发生 panic 时记录异常堆栈日志,输出统一的错误响应。

scss 复制代码
func Default() *Engine {
   debugPrintWARNINGDefault()
   engine := New()
   engine.Use(Logger(), Recovery())
   return engine
}

路由和路由组

提到路由,我们绕不开的一个概念就是路由树了,这里我们不打算深究路由树的原理,只简单介绍,有老哥想要进一步搞懂可去终于搞懂了Gin中的路由树转存失败路由树Gin 框架中核心概念之一,它采用了树的数据结构,准确来说就是 radix tree(压缩前缀树)

此先声明,本人水平有限,此处为自己的见解,想彻底搞懂路由和路由组可去看其他大神文章。

路由可看做是路由树中的一个节点,Engine 对象包含一个 addRoute 方法用于添加路由,它会将对应的路径和处理挂接到相应的请求树中,当有URL请求发送到后端,根据请求URL匹配到对应的路由,完成定义好的处理函数。

而路由组就如同是路由的父节点一般,我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对{}包裹同组的路由,这只是为了看着清晰,你用不用{}包裹功能上没什么区别。具体使用如下:

go 复制代码
func main() {
	r := gin.Default()
	userGroup := r.Group("/user")
	{
		userGroup.GET("/index", func(c *gin.Context) {...})
		userGroup.GET("/login", func(c *gin.Context) {...})
		userGroup.POST("/login", func(c *gin.Context) {...})

	}
	shopGroup := r.Group("/shop")
	{
		shopGroup.GET("/index", func(c *gin.Context) {...})
		shopGroup.GET("/cart", func(c *gin.Context) {...})
		shopGroup.POST("/checkout", func(c *gin.Context) {...})
	}
	r.Run()
}

Gin框架中的路由使用的是httprouter这个库。

gin.Context

这个对象里保存了请求的上下文信息,它是所有请求处理器的入口参数。

go 复制代码
type HandlerFunc func(*Context)

type Context struct {
  ...
  Request *http.Request // 请求对象
  Writer ResponseWriter // 响应对象
  Params Params // URL匹配参数
  ...
  Keys map[string]interface{} // 自定义上下文信息
  ...
}

你可以通过Context对象获取request请求中的上下文信息,Context提供了丰富的方法,比如请求中的URL参数,Header,Cookie,表单数据这些都可调用Context对象中的方法获取,这一系列方法实质是对http.Request对象的包装。

此外,Context给开发者提供了许多种响应形式,JSON,HTML,Yaml等,他会给每一种形式制定单独的渲染器,这些内置的渲染器足以应对绝大多数场景,如果你觉得不够用还可以自定义渲染器。

go 复制代码
func (c *Context) JSON(code int, obj interface{}) 
func (c *Context) HTML(code int, obj interface{})
func (c *Context) YAML(code int, obj interface{}) 
... 

// 自定义渲染 func (c *Context) Render(code int, r render.Render)

所有的渲染器最终还是需要调用的Context.Writer(http.ResponseWriter),将响应对象转换成字节流写到套接字中。

下期见兄弟们。

相关推荐
滑滑滑1 天前
后端实践-优化一个已有的 Go 程序提高其性能 | 豆包MarsCode AI刷题
青训营笔记
柠檬柠檬2 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户967136399652 天前
计算最小步长丨豆包MarsCodeAI刷题
青训营笔记
用户52975799354722 天前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold3 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵3 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104443 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1233 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记
用户916357440954 天前
AI刷题-动态规划“DNA序列编辑距离” | 豆包MarsCode AI刷题
青训营笔记
热的棒打鲜橙4 天前
数字分组求偶数和 | 豆包MarsCode AI刷题
青训营笔记