Hertz 源码解析—— hz 是怎么支持自定义模板功能的?

1,175 阅读3分钟

Hertz 源码解析—— hz 是怎么读取用户的自定义数据的?

前言

Hertz 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttpginecho 的优势,并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

这是我参加 Cloudwego Study Group 第二期的第二篇文章,是第一篇文章 Hertz 源码解析—— hz new 是怎么生成代码文件的 的下一篇文章,我也是由衷的希望第一次看到这篇文章的读者可以看一看上一篇文章,对我而言这应该是一个完整的系列。

上篇大致介绍了hz new 生成默认的代码时发生了什么,这一篇文章我将从上篇文章忽略的自定义模板入口开始来一步步的解释发生了什么。

如何使用自定义模板?

这里为官方文档的完整介绍,这里我简要做些许介绍,为解释后续代码逻辑打个基础

默认 layout 模板的简易示例

layouts:
  - path: biz/handler  // 用于解释代码生成路径
    delims:            // 可以添加自定义的统配符,默认为 {{ }}, 该字段默认其实可以忽略
      - ""             // 左通配符
      - ""						 // 右通配符
    body: ""					 // 模板内容,为 go template 语法

模板渲染参数文件的含义

{
  // 全局的渲染参数
  "*": {
    "GoModule": "github.com/hz/test", // 要和命令行指定的一致,否则后续生成model、handler等代码将使用命令行指定的mod,导致出现不一致。
    "ServiceName": "p.s.m", // 要和命令行指定的一致
    "UseApacheThrift": false // 根据是否使用"thrift"设置"true"/"false"
  },
  // router_gen.go 路由注册的渲染数据,
  // "biz/router"指向默认idl注册的路由代码的module,不要修改
  "router_gen.go": {
    "RouterPkgPath": "github.com/hz/test/biz/router"
  }
}

这里大家得有印象,此为这篇文章的基石

使用自定义模板参数的“入口”

我以官方示例中的范例为入口

hz new \
--mod=github.com/hertz/hello \
--idl=idl/hello.thrift \
--customize_layout=template/layout.yaml:template/data.json

我们从上篇文章被忽略的地方开始,从下面的逻辑来看分别接收自定义模板参数后会可能会执行 GenerateByService(layout)GenerateByConfig(dataPath) ,我们先来看看 dataPath == "" 的情况

接收自定义参数

cmd/hz/internal/app/app.go

step1 (1).png

分情况处理自定义参数

我这里直接大胆猜测,读取全部文件的代码和这部分使用默认参数的逻辑差不多!往下看

cmd/hz/internal/generator/layout.go

step2.png

生成文件前的最后准备

猜测正确!他们最后都开始了 generate code! 继续看看后续操作。

下面的没有标注的代码都出自 layout.go

cmd/hz/internal/generator/layout.go

step8 (1).png

step5.png

step6.png

step7.png

最后一步

看完上面的逻辑,就会发现在最后的 generator 之前,所有的准备都是准备好了。

最后就是生成文件了

cmd/hz/internal/generator/template.go

step_final.png

至此,我对于在自定义模板的情况时的梳理就结束了。和上一篇文章相比我又添加了许多之前的省略细节。如将上篇文章学习完,这篇文章也应该时可以轻松理解。

小结

这次分享的内容是以上一篇文章为基础。有前辈教我:做事不在多,在于精,在于每一次都有收获,有进步。

我希望我写的不是泛泛之谈,而是逐步加码,由浅入深的有用的文字。在这段时间我是在分享 hz 的源码实现,在慢慢的解读它,说不定不久就可以涉及 Hertz core 了呢 ?

本文正在参加技术专题18期-聊聊Go语言框架