这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
前言
本文主要内容为Go
语言HTTP
框架——Hertz
。
Hertz
是字节内部开源的http
框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性等特点。
基础使用
安装Hertz
安装Hertz
需要确保电脑已经正确安装了Go
,并且Go
的版本要>=1.15
。
执行以下命令进行安装Hertz
:
go install github.com/cloudwego/hertz/cmd/hz@latest
安装后进行验证,输入以下命令:
hz -v
如果能正确输出版本信息,如下,就说明已经安装好了。
hz version v0.5.2
生成示例代码
可以使用hz
命令直接生成示例代码,步骤如下:
- 在当前目录下创建
hertz
文件夹,进入该目录中 - 执行生成代码命令
hz new
或者使用hz new -module example
- 执行命名
go mod tidy
整理、拉取依赖
生成代码目录如下:
打开main.go
文件,添加以下代码
到此,一个简单的http服务就完成了,现在可以编译并启动Server
了。
go run main.go
运行命令,成功启动后,输出以下信息:
我们可以看到,服务已经正常启动,并且默认端口号为8888
,打开浏览器输入访问地址
http://127.0.0.1:8888/ping
访问后,可以看到浏览器输出一个json
,内容如下:
{"message":"pong"}
Hertz路由
Hertz
提供了多种路由规则,路由的优先级为:静态路由 > 命名路由 > 通配路由。
静态路由
Hertz
提供了GET
、POST
、PUT
、DELETE
、ANY
等方法用于注册路由。
路由组
Hertz
提供了路由组(Group)的能力,用于支持路由分组的功能。
参数路由
Hertz
支持使用 :name
这样的命名参数设置路由,并且命名参数只匹配单个路径段。
如果我们设置/hertz/:version
路由,匹配情况如下:
路径 | 是否匹配 |
---|---|
/hertz/v1 | 匹配 |
/hertz/v2 | 匹配 |
/hertz/v1/detail | 不匹配 |
/hertz/ | 不匹配 |
通过使用 RequestContext.Param
方法,我们可以获取路由中携带的参数。
h.GET("/hertz/:version", func(ctx context.Context, c *app.RequestContext) {
version := c.Param("version")
c.String(consts.StatusOK, "Hello %s", version)
})
通配路由
Hertz
支持使用 *path
这样的通配参数设置路由,并且通配参数会匹配所有内容。
如果我们设置/hertz/*path
路由,匹配情况如下
路径 | 是否匹配 |
---|---|
/hertz/v1 | 匹配 |
/hertz/v1/detail | 匹配 |
/hertz/ | 匹配 |
通过使用 RequestContext.Param
方法,我们可以获取路由中携带的参数。
h.GET("/hertz/:version/*action", func(ctx context.Context, c *app.RequestContext) {
version := c.Param("version")
action := c.Param("action")
message := version + " is " + action
c.String(consts.StatusOK, message)
})
参数绑定
Hertz
提供了 Bind
、Validate
、BindAndValidate
函数用于进行参数绑定校验。
绑定的作用是把http
请求的参数封装到定义的结构体里面方便开发使用,Hertz
使用的是tag
的方式进行绑定的。
Tag | 说明 |
---|---|
path | 绑定 url 上的路径参数,相当于 hertz 路由 :param 或 *param 中拿到的参数 |
form | 绑定请求的 body 内容 |
query | 绑定请求的 query 参数 |
header | 绑定请求的 header 参数 |
json | 绑定 json 参数 |
vd | 参数校验 |
绑定使用的是BindAndValidate
方法,使用方法如下:
Hertz Client
Hertz
提供了 Http Client
用于帮助用户发送 Http
请求,可以在代码的逻辑中请求第三方服务。
例如,使用GET
发送一个Http
请求:
func Get() {
c, err := client.NewClient()
if err != nil {
return
}
status, body, _ := c.Get(context.Background(), nil, "http://www.example.com")
fmt.Printf("status=%v body=%v\n", status, string(body))
}
使用POST
发送一个Http
请求:
func Post() {
c, err := client.NewClient()
if err != nil {
return
}
var postArgs protocol.Args
postArgs.Set("arg", "a") // 发送参数
status, body, _ := c.Post(context.Background(), nil, "http://www.example.com", &postArgs)
fmt.Printf("status=%v body=%v\n", status, string(body))
}
代码生成
Hertz
提供了代码生成工具 Hz
,hz
是 Hertz
框架提供的一个用于生成代码的命令行工具,hz
可以基于 thrift
和 protobuf
的 IDL
生成 Hertz
项目的脚手架。
先定义一个IDL
文件,如hello.thrift
namespace go hello.example
struct HelloReq {
// 添加 api 注解为方便进行参数绑定
1: string Name (api.query="name");
}
struct HelloResp {
1: string RespBody;
}
service HelloService {
HelloResp HelloMethod(1: HelloReq request) (api.get="/hello");
}
执行命令生成代码,并整理依赖:
hz new -idl hello.thrift
go mod tidy
生成的文件结构如下:
Hertz性能
Hertz
是一个高性能Web
框架,之所以高性能是因为以下几点:
- 使用高性能网络库
Netpoll
Json
编解码Sonic
,Sonic
是一个高性能Json
编解码库- 使用
sync.Pool
复用对象协议层数据解析优化
Hertz生态
Hertz
拥有非常丰富的扩展生态:
Http2
扩展opentelemetry
扩展- 国际化扩展
- 反向代理扩展
JWT
鉴权扩展Websocket
扩展- 丰富的代码示例
引用
字节内部视频——Go框架三件套详解(Web/RPC/ORM)