当前位置: 首页 > news >正文

[每周一更]-(第100期):介绍 goctl自动生成代码

在这里插入图片描述

​ 在自己组件库中,由于部分设计会存在重复引用各个模板的文件,并且基础架构中需要基础模块内容,就想到自动生成代码模板,刚好之前有使用过goctl,以下就简单描述下gozero中goctl场景和逻辑,后续自己借鉴将自己的自动生产逻辑完成再分享。

​ gozero 是一个支持微服务的 Golang Web 和 RPC 框架,它提供了一套工具用于快速生成代码。其中,goctl 是 GoZero 的一个重要工具,用于根据 API 定义文件自动生成代码。理解 goctl 自动生成代码模块的逻辑,有助于开发者快速上手并有效使用 GoZero 框架。

gozero 和 goctl 介绍

  • gozero:是一个基于 Go 语言的微服务框架,提供了 Web 和 RPC 支持,旨在提高开发效率并简化微服务架构的开发和维护。
  • goctl:是 GoZero 提供的一个命令行工具,用于根据定义文件自动生成代码,包括 API 接口、数据模型、服务逻辑等,goctl 也可以是 go-zero 的内置脚手架,是提升开发效率的一大利器,可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。

goctl 自动生成代码的逻辑

goctl 的工作流程大致分为以下几个步骤:

  1. 定义 API 文件:开发者编写一个 .api 文件,描述 API 的接口、请求和响应参数。
  2. 解析 API 文件:goctl 读取并解析 .api 文件,将其转换为内部的数据结构。
  3. 生成代码模板:根据解析后的数据结构,goctl 应用代码模板生成各类代码文件。
  4. 生成文件:将生成的代码模板输出到指定的目录中,供开发者使用和扩展。

详细步骤

1. 定义 API 文件

API 文件使用特定的语法描述服务接口。例如:

syntax = "v1"info(title: "User Service"description: "Service for user management"
)type (UserRequest {Name string `json:"name"`Age  int    `json:"age"`}UserResponse {Id   int    `json:"id"`Name string `json:"name"`}
)service user-api {@handler CreateUserpost /users (UserRequest) returns (UserResponse)
}
2. 解析 API 文件

goctl 读取 .api 文件并解析其内容,转换为内部的数据结构。解析器会识别文件中的语法,并将接口、请求和响应参数等信息提取出来。

3. 生成代码模板

解析后的数据结构会传递给代码生成器,代码生成器会使用预定义的模板生成代码。GoZero 使用 template 包或其他模板引擎来生成代码文件。例如,生成处理器代码、数据模型、路由配置等。

4. 生成文件

最终,生成的代码模板会输出到指定的目录中。例如,生成的代码文件可能包括:

  • handler 文件:包含处理请求的逻辑。
  • model 文件:包含数据模型定义。
  • router 文件:配置路由信息。

示例:使用 goctl 生成代码

假设我们有一个 user.api 文件,内容如下:

syntax = "v1"info(title: "User Service"description: "Service for user management"
)type (UserRequest {Name string `json:"name"`Age  int    `json:"age"`}UserResponse {Id   int    `json:"id"`Name string `json:"name"`}
)service user-api {@handler CreateUserpost /users (UserRequest) returns (UserResponse)
}

使用 goctl 命令生成代码:

goctl api go -api user.api -dir .

命令说明:

  • goctl api go:指定生成 Go 语言代码。
  • -api user.api:指定 API 文件。
  • -dir .:指定生成代码的输出目录。

生成的目录结构可能如下:

.
├── etc
│   └── user-api.yaml
├── user
│   ├── user.go
│   ├── userhandler.go
│   ├── userlogic.go
│   ├── usermodel.go
│   └── userservice.go
└── user-api.go
生成代码文件解释
  • user.go:主服务入口文件。
  • userhandler.go:包含 CreateUser 处理器的代码。
  • userlogic.go:包含业务逻辑处理的代码。
  • usermodel.go:包含数据模型的定义。
  • userservice.go:包含服务层的代码。
  • user-api.go:API 服务的初始化代码。

示例生成 API 服务

以下是一个简单的示例,演示如何使用 goctl 生成一个 API 服务:

API 描述文件(example.api)
info:title: Example APIversion: 1.0.0desc: This is an example APItypes:UserRequest {Name string `json:"name"`Age  int    `json:"age"`}UserResponse {ID   int    `json:"id"`Name string `json:"name"`Age  int    `json:"age"`}service:- getUserget /user/{id}returns (UserResponse)- createUserpost /userrequest (UserRequest)returns (UserResponse)
使用 goctl 生成代码

运行以下命令,使用 goctl 根据 API 描述文件生成代码:

bash
复制代码
goctl api go -api example.api -dir .
生成的目录结构
plaintext
复制代码
.
├── etc
│   └── example-api.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── handler
│   │   ├── createuserhandler.go
│   │   └── getuserhandler.go
│   ├── logic
│   │   ├── createuserlogic.go
│   │   └── getuserlogic.go
│   ├── svc
│   │   └── servicecontext.go
│   └── types
│       └── types.go
├── example.api
└── example.go
代码逻辑
  1. API 描述文件解析
    • goctl 读取 example.api 文件,解析出 getUsercreateUser 两个接口,以及 UserRequestUserResponse 数据类型。
  2. 生成配置文件
    • etc/example-api.yaml:用于存放服务配置,例如服务端口、数据库连接等信息。
  3. 生成代码文件
    • internal/config/config.go:用于加载和管理配置文件。
    • internal/handler:存放 HTTP 请求处理逻辑,每个接口对应一个处理函数。
    • internal/logic:存放具体的业务逻辑,每个接口对应一个逻辑处理函数。
    • internal/svc/servicecontext.go:用于初始化服务的上下文,管理服务依赖。
    • internal/types/types.go:定义请求和响应的数据类型。

优势

  • 自动化:通过描述文件自动生成代码,大大减少了手工编码的工作量。
  • 规范化:生成的代码符合 go-zero 框架的最佳实践,确保代码风格一致,结构清晰。
  • 高效:快速生成 API 服务,提高开发效率。

参考

  • api-demo
  • 微服务效率工具 goctl 深度解析(上)
  • goctl-api

相关文章:

  • 【归档】git使用
  • HCIA-RS实验-单臂配置
  • 小米路由器如何设置去广告功能,如何设置小米路由器的自定义Hosts(小米路由器如何去除小米广告、去除小米电视盒子开屏广告、视频广告)
  • 基于深度学习的在线选修课程推荐系统
  • 【六袆 - Java】Java 驱动连接Oracle数据库; Java单元测试 连接Oracle;
  • springcloud第4季 springcloud-gateway网关filter案例场景
  • 自定义类型:结构体+结构体内存对齐+结构体实现位段
  • linux系统——ping命令
  • qemu虚拟机安装麒麟v10 arm版系统
  • [自学记录09*]Unity Shader:在Unity里渲染一个黑洞
  • 零基础入门学用Arduino 第一部分(三)
  • Java算法-力扣leetcode-167. 两数之和 II - 输入有序数组
  • 元音 (音标) 和元音字母的区别
  • Linux Shell Script 编写入门
  • 【vuejs】vm.$set() 的原理解析和方法以及应用场景
  • $translatePartialLoader加载失败及解决方式
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • css布局,左右固定中间自适应实现
  • dva中组件的懒加载
  • github从入门到放弃(1)
  • JavaScript 奇技淫巧
  • Netty 4.1 源代码学习:线程模型
  • PAT A1050
  • PHP的Ev教程三(Periodic watcher)
  • Python学习笔记 字符串拼接
  • Redis中的lru算法实现
  • Shell编程
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Spring Cloud Feign的两种使用姿势
  • vue 个人积累(使用工具,组件)
  • Webpack 4x 之路 ( 四 )
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 程序员最讨厌的9句话,你可有补充?
  • 多线程事务回滚
  • 飞驰在Mesos的涡轮引擎上
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 力扣(LeetCode)21
  • 前端面试之闭包
  • 【云吞铺子】性能抖动剖析(二)
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • # 数仓建模:如何构建主题宽表模型?
  • #{}和${}的区别是什么 -- java面试
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #define,static,const,三种常量的区别
  • (2)空速传感器
  • (30)数组元素和与数字和的绝对差
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (Python第六天)文件处理
  • (阿里云万网)-域名注册购买实名流程
  • (七)理解angular中的module和injector,即依赖注入
  • (四)activit5.23.0修复跟踪高亮显示BUG