这是我参与「第五届青训营」伴学笔记创作活动的第 10 天
概述
Hertz 是字节内部的 HTTP 框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性特点。
package main
import(
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main() {
h := server.Default (server.WithHostPorts("127.0.0.1:8080"))
h.GET("/ping",func(c context.Context, ctx*app.RequestContext){
ctx.JSON(consts.Statusok,utils.H{"ping":"pong"})
})
h.Spin()
}
sever.Default 会自动集成中间件 sever.New 没有自动集成的中间件
h.Spin() 开启自旋等待
有钩子函数,可以有效实现业务功能
Hertz 服务器监听 8080 端口。而且hertz是两个上下文。
Hertz路由
Hertz 提供了 GET、POST、PUT、DELETE、ANY 等方法用于注册路由。
func RegisterRoute(h*server.Hertz){
h.GET("/get",func(ctx context.Context, c *app.RequestContext){
c.String(consts.Statusok, "get")
})
h.POST("/post",func(ctx context.Context, c *app.RequestContext){
c . String ( consts . Statusok , " post " )
})
h.PUT("/put", func(ctx context.Context, c *app.RequestContext){
c.String(consts.Statusok, "put")
})
h.DELETE("/delete",func(ctx context.Context, c *app.RequestContext){
c.String(consts.Statusok, "delete")
})
h.PATCH("/patch",func(ctx context.Context, c *app.RequestContext){
c.Stging(consts.Statusok, "patch")
})
h.HEAD("/head",func(ctx context.Context, c *app.RequestContext){
c.String(consts.Statusok, "head")
})
h.OPTIONS("/options", func(ctx context.Context, c *app.RequestContext){
c.String(consts.Statusok, "options")
})
}
路由组
Hertz 提供了路由组(Group)的能力,用于支持路由分组的功能。也支持参数路由和通配路由。 也支持中间件注册在路由组。
// Simple group: v1
v1 := h.Group("/v1")
// LoginEndpoint is a handler func
{
v1.POST("/Login",LoginEndpoint)
v1.POST("/submit",submitEndpoint)
v1.POST("/streaming_read",readEndpoint)
}
// Simple group: v2
v2 := h.Group("/v2")
{
V2.POST("/Login",LoginEndpoint)
v2.POST("/submit",submitEndpoint)
v2.POST("/streaming_read",readEndpoint)
}
Hertz提供了参数路由(命名路由)和通配路由,路由的优先级为:静态路由>参数路由>通配路由
- 静态路由:
/Login - 参数路由:
/Del/:id - 通配路由:
/src/*path
参数绑定与校验
hertz 使用开源库 go-tagexpr 进行参数的绑定及验证。提供了 Bind、Validata、BindAndValidate 函数用于参数绑定和校验
func main() {
r := server.New()
r.GET("/hello", func(c context.Context, ctx *app.RequestContext) {
// 参数绑定需要配合特定的go tag使用
type Test struct {
A string `query:"a" vd:"$!='Hertz'"`
}
// BindAndValidate
var req Test
err := ctx.BindAndValidate(&req)
...
// Bind
req = Test{}
err = ctx.Bind(&req)
...
// Validate,需要使用 "vd" tag
err = ctx.Validate(&req)
...
})
...
}
Hertz 中间件
服务端中间件
Hertz 服务端中间件是 HTTP 请求-响应周期中的一个函数,提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求, 例如记录每个请求或者启用CORS。
Hertz 提供了常用的 BasicAuth、CORS、JWT等中间件
// 方式一
func MyMiddleware() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
// pre-handle
// ...
c.Next(ctx)
}
}
// 方式二
func MyMiddleware() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
c.Next(ctx) // call the next middleware(handler)
// post-handle
// ...
}
}
客户端中间件
客户端中间件可以在请求发出之前或获取响应之后执行:
- 中间件可以在请求发出之前执行,比如统一为请求添加签名或其他字段。
- 中间件也可以在收到响应之后执行,比如统一修改响应结果适配业务逻辑。 实现一个中间件
func MyMiddleware(next client.Endpoint) client.Endpoint {
return func(ctx context.Context, req *protocol.Request, resp *protocol.Response) (err error) {
// pre-handle
// ...
err = next(ctx, req, resp)
if err != nil {
return
}
// post-handle
// ...
}
}