安装
wget -O gf "https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH)" && chmod +x gf && ./gf install -y && rm ./gf
验证安装成功
zsh
终端,可能会存在gf
别名冲突(git fetch
快捷指令),那么安装后(至少执行一次)请重启终端软件来继续使用。
$ gf -v
v2.6.2
Welcome to GoFrame!
Env Detail:
Go Version: go1.21.4 linux/amd64
GF Version(go.mod): cannot find go.mod
CLI Detail:
Installed At: /home/lee/.bin/gf
Built Go Version: go1.20.7
Built GF Version: v2.6.2
Git Commit: 2024-01-22 22:10:21 bde3219da1a3714ad85d89863aca1c345e1826bd
Built Time: 2024-01-23 10:31:37
Others Detail:
Docs: https://goframe.org
Now : 2024-01-26T16:29:44+08:00
Quick Run
# 初始化项目名为 demo 。
gf init demo -u
# 运行项目
cd demo
gf run main.go
# 访问 api
# http://127.0.0.1:8000/hello
# 访问 swagger
# http://127.0.0.1:8000/swagger
# 升级框架版本
gf up -a
理解
各个目录的作用,可以看工程目录设计
| 目录/文件名称 | 说明 | 描述 |
| --- | --- | --- |
| `api` | 对外接口 | 对外提供服务的输入/输出数据结构定义。考虑到版本管理需要,往往以`api/xxx/v1...`存在。 |
| `hack` | 工具脚本 | 存放项目开发工具、脚本等内容。例如,`CLI`工具的配置,各种`shell/bat`脚本等文件。 |
| `internal` | 内部逻辑 | 业务逻辑存放目录。通过`Golang internal`特性对外部隐藏可见性。 |
| `- cmd` | 入口指令 | 命令行管理目录。可以管理维护多个命令行。 |
| `- consts` | 常量定义 | 项目所有常量定义。 |
| `- controller` | 接口处理 | 接收/解析用户输入参数的入口/接口层。 |
| `- dao` | 数据访问 | 数据访问对象,这是一层抽象对象,用于和底层数据库交互,仅包含最基础的 `CURD` 方法 |
| `- logic` | 业务封装 | 业务逻辑封装管理,特定的业务逻辑实现和封装。往往是项目中最复杂的部分。 |
| `- model` | 结构模型 | 数据结构管理模块,管理数据实体对象,以及输入与输出数据结构定义。 |
| `- do` | 领域对象 | 用于`dao`数据操作中业务模型与实例模型转换,由工具维护,用户不能修改。 |
| `- entity` | 数据模型 | 数据模型是模型与数据集合的一对一关系,由工具维护,用户不能修改。 |
| `- service` | 业务接口 | 用于业务模块解耦的接口定义层。具体的接口实现在`logic`中进行注入。 |
| `manifest` | 交付清单 | 包含程序编译、部署、运行、配置的文件。常见内容如下: |
| `- config` | 配置管理 | 配置文件存放目录。 |
| `- docker` | 镜像文件 | `Docker`镜像相关依赖文件,脚本文件等等。 |
| `- deploy` | 部署文件 | 部署相关的文件。默认提供了`Kubernetes`集群化部署的`Yaml`模板,通过`kustomize`管理。 |
| `- protobuf` | 协议文件 | `GRPC`协议时使用的`protobuf`协议定义文件,协议文件编译后生成`go`文件到`api`目录。 |
| `resource` | 静态资源 | 静态资源文件。这些文件往往可以通过 资源打包/镜像编译 的形式注入到发布文件中。 |
| `go.mod` | 依赖管理 | 使用`Go Module`包管理的依赖描述文件。 |
| `main.go` | 入口文件 | 程序入口文件。 |
对外接口包含两部分:接口定义(api)+接口实现(controller)。
业务实现包含两部分:业务接口(service)+业务封装(logic)。
结构模型:model包的职责类似于三层架构中的Model模型定义层。模型定义代码层中仅包含全局公开的数据结构定义,往往不包含方法定义。 这里需要注意的是,这里的model不仅负责维护数据实体对象(entity)结构定义,也包括所有的输入/输出数据结构定义,被api/dao/service共同引用。这样做的好处除了可以统一管理公开的数据结构定义,也可以充分对同一业务领域的数据结构进行复用,减少代码冗余。
数据访问:dao包的职责类似于三层架构中的DAL数据访问层,数据访问层负责所有的数据访问收口。
项目启动
main.go
入口main.go
,实例项目中,默认会执行internal/cmd
包的Main
对象Run
命令引导程序启动。
框架的核心组件均需要传递context
上下文参数,这里使用gctx.New
表示创建一个带链路跟踪特性的context
上下文对象给下游链路。
- 引导启动
internal/cmd/cmd.go
框架的命令行管理默认采用了结构化的对象管理方式,命令管理
Main
对象的Run
命令的主要作用是做引导启动,将一些动态初始化的逻辑放到Main
的Run
方法中。在项目模板中,默认创建一个HTTP Server
,然后通过分组路由的方式注册路由,并启动HTTP Server
。随后HTTP Server
将会阻塞运行,它同时也会异步监听系统信号,直至收到退出信号后,它会优雅关闭连接随后退出进程。
- 路由注册
internal/cmd/cmd.go
细的HTTP Server路由介绍路由管理
模板中使用了Group方法创建了分组路由,框架的HTTP Server支持多种路由注册方式
- 路由对象
internal/controller/hello/hello_v1_hello.go
模板中的路由对象Hello只有一个路由Hello,仅用于模板示例作用。 多数场景下我们简单地带了一个小写的前缀c表示controller的缩写。
api/hello/v1/hello.go
Hello方法对应的路由信息是定义到HelloReq输入参数对象中的
统一的中间件返回统一的数据结构,统一路由对象的方法管理路由的方式路由注册-规范路由
- 阻塞运行
internal/cmd/cmd.go
通过HTTP Server
的Run
方法启动HTTP Server
,随后HTTP Server
将会阻塞运行接收客户端请求,并监听进程信号,用于HTTP Server
重启/关闭。
GoFrame框架的HTTP Server带有非常多的特性,WEB服务开发
项目配置
目录结构,各个目录的作用,可以看工程目录设计
- 工程配置 hack目录下是GoFrame框架提供的开发工具的配置,与业务配置独立。通常以config.yaml命名。
业务项目运行所需的配置,用于业务项目部署运行,存放于manifest/config目录下。
-
配置对象 业务配置可以通过框架独立的配置组件来访问,g.Cfg()单例对象将会自动读取manifest/config目录下的配置文件,配置组件的功能非常强大
-
单例对象 虽然框架的组件是模块化、低耦化设计的,但为了给与业务项目使用的方便,框架同时提供了一些常用的单例对象获取,例如:g.Cfg()/g.DB()/g.Log()等等
单例对象的便捷之处在于,它会自动通过g.Cfg()配置对象自动获取既定配置项下的配置,并自动初始化单例对象。不同的单例对象,自动读取的配置项不同。
要点介绍
- 接口定义
api/hello/v1/hello.go
接口注册文件位于api目录下,在API结构体的属性中包含一些标签。其中结构体属性的v标签表示校验规则,请求参数进入HTTP Server后将会被自动执行校验(框架有非常强大的数据校验组件)
- 路由注册
internal/cmd/cmd.go
路由注册往往在cmd包中,在本项目中,仍旧采用灵活的分组路由注册方式。在部分路由中带有鉴权中间件,这部分路由需要鉴权后才能访问,可看,路由管理-中间件/拦截器
- 常量管理
项目的全局访问常量位于 internal/consts
包下,供项目所有的包全局可访问,全局常量通过不同的文件以及名称命名前缀来区分不同的业务模块。
注意:非公开的常量建议放到对应的包下面闭环维护。
- 控制器定义
internal/controller/hello/hello_v1_hello.go
不带有任何的业务逻辑,负责API接口数据结构的输入与输出,调用一个或多个service实现具体的业务逻辑。
- 数据库访问
推荐使用dao/do/entity的方式操作数据库,这些文件都是通过开发工具自动生成的,由开发工具统一维护。 代码生成方式通过 make dao命令,或者gf gen dao命令。查看Dao封装设计和数据规范-gen dao
-
业务模型 内部模块间交互的数据结构由model包维护,供全局访问。数据模型与业务模型
-
服务接口 为了降低业务项目内部模块间的耦合,框架将模块间的依赖抽象为了接口,由internal/service包维护。 internal/service可以由开发者自定义维护接口,也可以通过internal/logic业务封装的代码按照一定规则自动生成接口代码文件。模块规范-gen service
-
业务实现 业务的具体实现由internal/logic包维护,通过依赖注入的方式注册具体的实现对象到internal/service包下。
- 依赖注入 业务实现的依赖注入使用的是匿名包初始化方法init,在匿名包初始化方法内部使用service.RegisterXxx的方式注入具体的接口实现对象。
- 增加引入(仅一次)
代码生成
框架的目的是让开发者将精力聚焦于业务逻辑实现本身。controller
,dao/entity/do
,service
都可以通过开发工具生成