前言这篇文章不是 Hertz 全量教程而是一份项目驱动下的 Hertz 学习索引笔记。我的目标是先建立起一条足够清晰的主线支撑自己去读一个真实的 Hertz 项目并且在后续项目学习和面试复习时能快速回查。这份笔记主要覆盖Hertz 是什么Engine / Route / Middleware 的作用RequestContext和context.Context的区别BindAndValidate在项目中的定位hz与thrift的关系Hertz 项目常见的handler - service - dal分层思路目录1. Overview2. Engine3. Route4. Middleware5. RequestContext6. Binding Validate7. hz 与 Thrift8. Handler / Service / DAL 分层9. 项目阅读主线10. Hertz 常用能力速查11. 当前阶段可跳过内容12. 面试复习速记1. OverviewHertz 是一个 Go Web 框架用来构建 HTTP 服务。对当前阶段来说最重要的定位不是去理解它全部底层细节而是先明确Hertz 和 Gin 属于同类框架都承担服务启动、路由、中间件、请求处理、响应返回这些核心职责。Hertz 的特点主要体现在更强调工程化更适合和 IDL / 代码生成工具配合更贴近微服务风格对大项目的接口组织更友好当前阶段可以把它理解成一个支持工程化代码组织的 Go Web 框架2. Engine2.1 什么是 EngineHertz 对外暴露的核心服务对象通常通过下面两种方式创建h : server.Default(...)或者h : server.New(...)后续所有操作一般都围绕这个服务对象展开注册路由注册中间件启动服务2.2server.Hertzserver.Hertz是 Hertz 提供给开发者直接操作的核心服务对象负责启动 HTTP 服务挂载路由挂载中间件支持优雅退出项目里通常不需要关心它内部是怎么实现的只需要知道以后看到h : server.Default(...)这个h就是整个服务的核心入口对象。2.3Spin()常见调用h.Spin()作用启动 Hertz 服务开始监听端口处理请求在退出时执行优雅关闭可以粗略类比为 Gin 中常见的r.Run(...)但 Hertz 的Spin()更强调“启动 运行 退出控制”这一整套过程。2.4server.Default(...)的常见理解例如h : server.Default(server.WithHostPorts(127.0.0.1:8080))可以理解成创建一个监听127.0.0.1:8080的 Hertz 服务这一层先掌握“怎么创建服务对象”和“怎么启动服务”即可不需要深挖框架内部字段。3. Route3.1 Route 的作用路由负责把 “HTTP 方法 URL 路径” 映射到具体的 handler例如h.POST(/user/login, handler)表示收到POST /user/login交给handler执行3.2 路由的三种类型1Static Route静态路由/user/login路径固定没有变量。2Parametric Route参数路由/user/:id其中:id是路径参数占位符。3Wildcard Route通配路由/static/*filepath用于匹配后续整段路径。3.3 路由参数获取参数路由和通配路由都可以通过c.Param(id) c.Param(filepath)获取本次请求中的动态参数值。示例h.GET(/user/:id, func(ctx context.Context, c *app.RequestContext) { id : c.Param(id) })这里要区分注册路由时定义的是参数名和位置请求真正进来时c.Param(...)取的是参数的实际值3.4 路由组Group路由组的作用为一组路由统一设置前缀为一组路由统一挂载 middleware例如v1 : h.Group(/v1) v1.GET(/ping, handler)最终路径就是/v1/ping4. Middleware4.1 Middleware 的定义Middleware 是在真正业务 handler 执行之前或之后统一执行的一层通用逻辑常见用途token 校验登录拦截跨域处理日志打印请求耗时统计当前用户恢复4.2Use(...)常见写法h.Use(SomeMiddleware)Use(...)的作用是把 middleware 注册到请求处理链中需要区分Use不是 middleware 本身Use也不会“生成 middleware”Use是注册动作4.3 Middleware 的注册层级全局级别h.Use(m1, m2)作用于所有路由。路由组级别api : h.Group(/api, AuthMiddleware)作用于某个路由组。单路由级别只作用于某个具体接口。4.4 Middleware 与 Handler 的关系两者函数签名可以相同都是app.HandlerFunc但职责不同Handler负责具体业务逻辑Middleware负责通用逻辑可以理解成middleware 是“通用处理层”handler 是“业务处理层”4.5c.Next(ctx)在 middleware 中Next表示当前 middleware 执行完成后继续执行后续 middleware 或 handler如果不调用Next请求通常会在当前 middleware 被拦截。4.6 BasicAuth例如v1 : h.Group(/v1, basic_auth.BasicAuth(map[string]string{test: test}))作用创建/v1路由组给这组路由挂载 BasicAuth 中间件这里的basic_auth.BasicAuth(...)是一个生成 middleware 的函数。4.7 Server-side 与 Client-side MiddlewareServer-side Middleware作用于服务端收到的请求。当前业务项目主要关注这一类。Client-side Middleware作用于程序主动发出的请求例如服务调用第三方 HTTP API。当前阶段只需知道概念不需要深入。5. RequestContext5.1 什么是RequestContextHertz handler 的常见写法func Handler(ctx context.Context, c *app.RequestContext)其中c *app.RequestContext是 Hertz 中处理 HTTP 请求和响应的核心对象。可以类比为 Gin 中的*gin.Context5.2 常用能力取路径参数c.Param(id)取请求头c.GetHeader(authorization)返回 JSONc.JSON(...)返回字符串c.String(...)参数绑定与校验c.BindAndValidate(req)5.3RequestContext与context.Context的区别RequestContext负责 HTTP 层路径参数请求头响应写回参数绑定context.Context负责程序调用链层timeout / deadlinecanceltrace / request id少量跨层公共信息可以概括为RequestContextHTTP 视角context.Context调用链视角6. Binding Validate6.1BindAndValidate常见调用err : c.BindAndValidate(req)作用从请求中取参数绑定到目标结构体做参数校验6.2 在项目中的意义这一步属于 handler 层职责作用是让 handler 先把 HTTP 请求整理成业务可用的 struct再把这个 struct 交给 service这样 service 层就不需要直接处理原始 HTTP 参数。6.3 当前阶段掌握标准只需要明确BindAndValidate是参数绑定入口它会把请求转成 struct它负责基础校验它属于 handler 层而不是 service 层7. hz 与 Thrift7.1idl/*.thriftThrift 文件是接口和数据结构的定义文件它负责描述有哪些接口请求结构长什么样响应结构长什么样HTTP 路径是什么service 方法是什么它不是业务逻辑实现代码。7.2hzhz是 Hertz 的代码生成工具负责读取 thrift / IDL生成 route / handler / model 等代码骨架7.3 二者关系可以记成IDL(thrift) 图纸 hz 生成代码的工具 生成出来的 .go 骨架 手写 handler/service 业务实现7.4 项目中的意义当前项目中的很多 route、handler、model并不是完全手写的而是先写 IDL再由 hz 生成骨架最后补业务逻辑8. Handler / Service / DAL 分层当前项目中常见的分层方式8.1 Handler职责接 HTTP 请求绑定参数调用 service返回响应8.2 Service职责写核心业务逻辑操作 Redis / MySQL做业务分支判断生成 token / 处理状态等8.3 DAL职责访问底层存储包括 MySQL / Redis 等8.4 主链路理解一个典型的业务流程前端请求 ↓ handler ↓ service ↓ dal / Redis / MySQL ↓ handler 返回响应9. 项目阅读主线阅读 Hertz 项目时建议按下面顺序9.1 先看main.go看服务怎么创建middleware 怎么注册路由怎么加载服务怎么启动9.2 再看 middleware看token 校验登录拦截跨域全局逻辑9.3 再选一条业务主线比如loginsignblog likevoucher 秒杀9.4 只按需查 struct对于大型生成 model 文件不从头读到尾只查当前链路需要的结构体例如UserLoginFromUserUserDTOResult10. Hertz 常用能力速查创建服务h : server.Default(...) h : server.New(...)注册中间件h.Use(middleware)注册路由h.GET(/path, handler) h.POST(/path, handler)创建路由组api : h.Group(/api)取路径参数c.Param(id)取请求头c.GetHeader(authorization)绑定请求c.BindAndValidate(req)返回 JSONc.JSON(...)返回字符串c.String(...)启动服务h.Spin()11. 当前阶段可跳过内容以下内容当前阶段只需知道存在不需要深挖custom protocolstream read / stream writesignal waiter 深层实现SetFormValueFunctransport 扩展client-side middleware 深挖route / engine 底层源码细节这些都属于框架高级扩展能力不属于当前业务项目主线必需知识。12. 面试复习速记12.1 如何定义 HertzHertz 是 Go Web 框架负责服务启动路由注册中间件挂载请求处理响应返回12.2server.Default/server.New用于创建 Hertz 服务对象。12.3Spin()启动服务并支持优雅退出。12.4Use(...)用于注册 middleware。12.5 Middleware 是什么请求进入真正业务 handler 前后执行的通用逻辑层。12.6RequestContextHTTP 请求/响应上下文对象负责取参数取 header返回响应参数绑定12.7context.Context程序内部调用链上下文负责timeoutcanceltrace / request id少量跨层公共数据12.8BindAndValidate绑定请求参数并校验属于 handler 层职责。12.9 Thrift / hzthrift定义接口蓝图hz根据蓝图生成代码骨架12.10 项目分层handlerHTTP 层service业务层dal存储层结语这份笔记的用途不是替代官方文档而是作为阅读 Hertz 项目时的索引文档 面试前的快速复习提纲如果后面继续深入项目可以再在这份笔记上补login 主线sign / bitmapblog like / feedvoucher 秒杀