文章

golang - 框架实战(go-zero)

golang - 框架实战(go-zero)

golang框架实战(go-zero)

以前我用最习惯用的API框架是gin,由于各家公司都有高人坐镇,所以并不是gin这门武艺一统江湖。

我来这家公司就是以go-zero统一内部所有项目,不仅用了API功能,还使用了RPC进行微服务接入。那么我现在把一场实战演示出来。

项目创建

我使用当时最新版go-zero标签:v1.9.0,如果已经有新版的建议用新版的,很大因素是新版本会修复一些旧版本问题,就比如nacos-sdk-go(项目一直用的时候有个问题,虽然影响不大,但是需要自身业务逻辑去处理,我接手后才进行了版本升级)。

1
https://github.com/zeromicro/go-zero/tree/v1.9.0

首先照着安装goctl ,其他的可以按照官方教程,也可以使用我的习惯(跟网上还是有区分)。

1
2
3
4
5
6
go mod init gozero-api
mkdir api-file && cd api-file
touch demo.api
goctl api go -api demo.api -dir ..
cd ../
go mod tidy

文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
syntax = "v1"

//goctl api go -api demo.api -dir ..
info (
	title: "我的一个demo"
	data:  "2025-09-25"
)

import (
	"result.api"
)

type (
	DemoReq {
		Say string `json:"say"` //要发送的文字
	}
)

@server (
	group:      api/demo
	middleware: ApiMiddleware,AuthMiddleware
)
service main {
	@doc (
		summary: "一个demo"
	)
	@handler say
	post /api/demo/say/:name (DemoReq) returns (ResultResp)
}


1
2
3
4
5
6
7
8
9
syntax = "v1"

//ResultResp 统一返回结果
type ResultResp {
    Code int `json:"code"`
    Msg string `json:"msg"`
    Data interface{} `json:"data"`
}

项目改造

通过上文我们简单创建了一个api项目,包含了路由层handler、逻辑层 logic。缺少服务层(业务服务、数据服务等)

端口默认8888 (./etc/main.yaml有配置)

以下是个人建议的方式,并非一定按照我的思路,可以借鉴下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 在项目根目录进行目录创建,目录名称个人习惯而定,我定义了comm、doc、model、service

# comm 公共依赖包自研目录
# 例如 mkdir -p comm/defines 存放内部的常量值
mkdir comm

# doc 项目有需求对底层数据结构发生重大变更时,补充文档说明,例如sql的表结构变更
mkdir doc

# model 存放数据实体,仅仅实体的定义用于ORM中的M,最好内部增加包区分(便于按照数据作用域区分)
# 例如 mkdir -p model/uc 存放的都是用户中心(user center)相关的实体
mkdir model

# service 实际服务层
# 例如 mkdir -p service/iuc  用来提供用户中心内部服务,里面包含业务服务和数据服务
# 同时可以增加自己的DML层、DAL层
mkdir service

有朋友建议我把这些放到internal目录下,理由:倘若我们api项目被其他项目引入,这样自己的业务和数据都能得到很好的保护(指的引用方式)。

我的建议是:这个api项目是你们自己的项目,若让另一个api或者web项目引入,那这个应当剥离出一个公共库项目使用,不含对外提供服务的业务逻辑在里面。

朋友又跟我说:好不容易写好的model、comm,我想再另一个项目中用,那怎么办呢?

我的建议:重新申请一个公共lib项目,把这些放到里面进行统一维护。例如我们原来都是单体项目,后来要改成微服务,那就得把公共的抽离出来了(一生二,二生三,三生万物)。一个小项目发展成为一个大集团合作项目 – 生态。

项目继续改造:

把单一多人共同频繁操作的文件,改成独立编辑的文件。

  1. internal/types/types.go 拆出来:

    1
    2
    3
    4
    5
    6
    
    tree internal/types/
    -- internal/types/
      |-- type.go
      |-- response.go
      |-- demo.go
      |-- uc.go
    

    多人共同开发新业务,新增接口或者修改接口协议时,减少冲突范围

  2. internal/handler/routes.go 拆出来:

    1
    2
    3
    4
    5
    6
    
    tree internal/handler/
    -- internal/handler/
      |-- routes.go
      |-- routes_demo.go
      |-- routes_uc.go
       
    
  3. 废弃使用internal/config/config.go ,放到 comm/conf/config.go ,可以增加全局变量便于其他位置直接使用。

日志改造

项目框架自带access日志,你可以想象一下nginx的日志,会记录每一条请求。

但是我们的Request和Respnse都是放在content中,并没有实现json列的方式,想要搜集到es,需要logstash进行读取然后json化,我这边进行了直接改造,便于filebeat采集。

我们可以增加一个accessMiddlerware,或者logMiddlerware。然后处理我们的上下文数据。

本文由作者按照 CC BY 4.0 进行授权