go-zero学习 第二章 进阶之API_go-zero syntax是用来干什么的(2)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

middleware: AuthInterceptor // 对当前 Foo 语法块下的所有路由添加中间件,不需要则请删除此行
maxBytes: 1024 // 对当前 Foo 语法块下的所有路由添加请求体大小控制,单位为 byte,goctl 版本 >= 1.5.0 才支持
)
service Foo {
// 定义没有请求体和响应体的接口,如 ping
@handler ping
get /ping

// 定义只有请求体的接口,如更新信息
@handler update
post /update (UpdateReq)

// 定义只有响应体的结构,如获取全部信息列表
@handler list
get /list returns ([]ListItem)

// 定义有结构体和响应体的接口,如登录
@handler login
post /login (LoginReq) returns (LoginResp)

// 定义表单请求
@handler formExample
post /form/example (FormExampleReq)

// 定义 path 参数
@handler pathExample
get /path/example/:id (PathExampleReq) returns (PathExampleResp)
}

其他示例:https://go-zero.dev/docs/tasks/dsl/api#快速入门


1 syntax 语句
syntax 语句用于标记 api 语言的版本,不同的版本可能语法结构有所不同,随着版本的提升会做不断的优化,当前版本为 v1

示例:

syntax = “v1”


2 info 语句
info 语句是 api 语言的 meta 信息,其仅用于对当前 api 文件进行描述,暂不参与代码生成,其和注释还是有一些区别,注释一般是依附某个 syntax 语句存在,而 info 语句是用于描述整个 api 信息的,当然,不排除在将来会参与到代码生成里面来。

示例:

info(
title : “XXX系统”
author: “哈哈哈”
email: “123456@qq.com”
version: “1.0.0.0”
)


3 import 语句
import 语句是在当前 api 中引入其他 api 文件的语法块,其支持相对/绝对路径,不支持 package 的设计,如 time.Time

示例:

// 单行 import
import “foo”
import “/path/to/file”

// import 组
import ()
import (
“bar”
“relative/to/file”
)


4 结构体语句(HTTP 服务的请求/响应体语句)
api 中的数据类型基本沿用了 Golang 的数据类型,用于对 rest 服务的请求/响应体结构的描述。

示例1:

// 别名类型 [1]
type Int int
type Integer = int

// 空结构体
type Foo {}

// 单个结构体
type Bar {
Foo int json:"foo"
Bar bool json:"bar"
Baz []string json:"baz"
Qux map[string]string json:"qux"
}

type Baz {
Bar json:"baz"
// 结构体内嵌 [2]
Qux {
Foo string json:"foo"
Bar bool json:"bar"
} json:"baz"
}

// 空结构体组
type ()

// 结构体组
type (
Int int
Integer = int
Bar {
Foo int json:"foo"
Bar bool json:"bar"
Baz []string json:"baz"
Qux map[string]string json:"qux"
}
)

示例2(实际使用):

type (
/* 1 公用类 */
BaseModel {
Id int64 json:"id" // id
Name string json:"name,optional" // 名称
Data string json:"data,optional" // 数据:string
}

/* 2 公共返回 */
BaseModelResp {
Code string json:"code" // 状态码
Message string json:"message" // 提示信息
Data []*BaseModel json:"data,optional"
}

/* 3 分类标签接口的返回数据 */
GetClassLabelResp {
Code string json:"code" // 状态码
Message string json:"message" // 提示信息
ClassLabelList []*BaseModel json:"classLabelList" // 分类标签集合:id-名称
}
)

注意

  1. 虽然语法上支持别名,但是在语义分析时会对别名进行拦截,这或在将来进行放开。
  2. 虽然语法上支持结构体内嵌,但是在语义分析时会对别名进行拦截,这或在将来进行放开。

除此之外

  1. 目前 api 语法中虽然支持了数组的语法,但是在语义分析时会对数组进行拦截,目前建议用切片替代,这或在将来放开。
  2. 不支持 package 设计,如 time.Time

5 @server 语句
@server 语句是对一个服务语句的 meta 信息描述,其对应特性包含但不限于:

  • jwt 开关
  • 中间件
  • 路由分组
  • 路由前缀

示例1:

// 空内容
@server()

// 有内容
@server (
// jwt 声明
// 如果 key 固定为 “jwt:”,则代表开启 jwt 鉴权声明
// value 则为配置文件的结构体名称
jwt: Auth

// 路由前缀
// 如果 key 固定为 “prefix:”
// 则代表路由前缀声明,value 则为具体的路由前缀值,字符串中没让必须以 / 开头
prefix: /v1

// 路由分组
// 如果 key 固定为 “group:”,则代表路由分组声明
// value 则为具体分组名称,在 goctl生成代码后会根据此值进行文件夹分组
group: Foo

// 中间件
// 如果 key 固定为 middleware:”,则代表中间件声明
// value 则为具体中间件函数名称,在 goctl生成代码后会根据此值进生成对应的中间件函数
middleware: AuthInterceptor

// 超时控制
// 如果 key 固定为 timeout:”,则代表超时配置
// value 则为具体中duration,在 goctl生成代码后会根据此值进生成对应的超时配置
timeout: 3s

// 其他 key-value,除上述几个内置 key 外,其他 key-value
// 也可以在作为 annotation 信息传递给 goctl 及其插件,但就
// 目前来看,goctl 并未使用。
foo: bar
)

示例2(实际使用):

@server(
jwt: Auth
middleware: CheckUrl
group: app/appSystem
prefix: /app/appSystem
)


6 @doc 语句
@doc 语句是对单个路由的 meta 信息描述,一般为 key-value 值,可以传递给 goctl 及其插件来进行扩展生成。

示例1:

// 单行 @doc
@doc “foo”

// 空 @doc 组
@doc ()

// 有内容的 @doc 组
@doc (
foo: “bar”
bar: “baz”
)

示例2(实际使用):

@doc(
summary: “XXX列表”
)


7 @handler 语句
@handler 语句是对单个路由的 handler 信息控制,主要用于生成 golang http.HandleFunc 的实现转换方法。

示例:

@handler foo

@handler GetClassLabelHandler

注意:不论定义的handler是否有handler后缀,goctl根据api实际生成的代码文件均会以xxxhandler为后缀,所以在api中定义handler时加不加handler后缀没有意义。


8 HTTP 路由语句
路由语句是对此 HTTP 请求的具体描述,包括请求方法,请求路径,请求体,响应体信息。

示例:

// 没有请求体和响应体的写法
get /ping

// 只有请求体的写法
get /foo (foo)

// 只有响应体的写法
post /foo returns (foo)

// 有请求体和响应体的写法
post /foo (foo) returns (bar)


9 HTTP 服务声明语句
示例:

// 带 @server 的写法
@server (
prefix: /v1
group: Login
)
service user {
@doc “登录”
@handler login
post /user/login (LoginReq) returns (LoginResp)

@handler getUserInfo
get /user/info/:id (GetUserInfoReq) returns (GetUserInfoResp)
}
@server (
prefix: /v1
middleware: AuthInterceptor
)
service user {
@doc “登录”
@handler login
post /user/login (LoginReq) returns (LoginResp)

@handler getUserInfo
get /user/info/:id (GetUserInfoReq) returns (GetUserInfoResp)
}

// 不带 @server 的写法
service user {
@doc “登录”
@handler login
post /user/login (LoginReq) returns (LoginResp)

@handler getUserInfo
get /user/info/:id (GetUserInfoReq) returns (GetUserInfoResp)
}


10 注释语句
api 领域特性语言中有 2 种格式:

  • 单行注释以 // 开始,行尾结束。
  • 多行注释(文档注释)以 /* 开始,以第一个 */ 结束。

3 API服务代码实战

参考1:请求参数

前面讲解了api文件的语法,这里在使用时具体讲解一些细节,主要有以下内容:

  1. path参数
  2. form参数
  3. json参数
  4. header参数
  5. 参数修饰符
  6. 文件上传/下载
  7. 请求体大小限制
  8. api分组
  9. 中间件
  10. 统一返回信息
  11. 鉴权【需要结合rpc服务,下一节再讲解】

1、2、3、4、5、6、7都是针对请求参数,1、2、3、4可以划归为一组,在绑定参数时,只能选择1、2、3、4其中一个。

请求参数:

标签类型描述提供方使用范围示例
path路由path,如/foo/:idgo-zerorequestpath:"id"
form标志请求体是一个form(POST方法时)或者一个query(GET方法时/search?name=keyword)go-zerorequestform:"name"
jsonjson序列化taggolangrequest、responsejson:"fooo"
headerHTTP header,如 Name: valuego-zerorequestheader:"name"

参数修饰符:

标签类型描述提供方使用范围示例
optional定义当前字段为可选参数go-zerorequestjson:"name,optional"
options定义当前字段的枚举值,多个以,隔开go-zerorequestjson:"gender,options=male,emale"
default定义当前字段默认值go-zerorequestjson:"gender,default=male"
range定义当前字段数值范围go-zerorequestjson:"age,range=[0:120]"

3.1 请求参数、文件上传/预览、分组示例

代码:请求参数、文件上传/预览、分组示例 代码示例
1 api文件:

syntax = “v1”

info(
title : “go-zero-api”
desc: “ucenter”
author: “ximuqi”
email: “xxx”
version: “0.0.1”
)

type (
/* 1 公用类(json) */
BaseModelJson {
Id int64 json:"id" // id
Name string json:"name,optional" // 名称
Data string json:"data,optional" // 数据
}

/* 2 公用类(form) */
BaseModelForm {
Id int64 form:"id" // id
Name string form:"name,optional" // 名称
Data string form:"data,optional" // 数据
}

/* 3 公用类 Path */
PathReq {
Id int64 path:"id" // id
Name string path:"name" // 名称
}

/* 4 上传文件 */
FileUploadReq {
Id int64 form:"id" // 父级-id
Type int64 form:"type,optional" // 类型 1:证书文件;2:私钥文件
FileList []*byte form:"fileList,optional" // 文件列表
}

/* 5 下载/预览文件 */
FileShowReq {
Id int64 form:"id" // 文件-id
FileUrl string form:"fileUrl,optional" // 文件地址
}

/* 6 用户账号密码登录 model */
UserModel {
Account string json:"account" // 账号
Password string json:"password" // 密码
Gender int64 json:"gender,options=1:2:3" // 性别 1:未设置;2:男性;3:女性
Current int64 json:"current,optional,default=1" // 当前页码
PageSize int64 json:"pageSize,optional,default=20" // 每页数量
}

/* 7 用户登录返回 model */
UserLoginResp {
Id int64 json:"id" // 用户id
Account string json:"account" // 账号
Username string json:"username" // 登录账号
Gender int64 json:"gender" // 性别 1:未设置;2:男性;3:女性
Avatar string json:"avatar" // 头像
AccessToken string json:"token" // token
AccessExpire int64 json:"accessExpire" // 过期时间戳
RefreshAfter int64 json:"refreshAfter" //
}
)

@server(
middleware: Check
group: ucenter
prefix: /ucenter
)
service uCenter {
@doc(
summary: “1 json参数”
)
@handler jsonParam
post /jsonParam (BaseModelJson) returns (BaseModelJson)

@doc(
summary: “2 表单参数(post)”
)
@handler formParamPost
post /formParamPost (BaseModelForm) returns (BaseModelJson)

@doc(
summary: “3 表单参数(Get)”
)
@handler formParamGet
get /formParamGet (BaseModelForm) returns (BaseModelJson)

@doc(
summary: “4 path参数”
)
@handler pathParam
get /pathParam/:id/:name (PathReq) returns (BaseModelJson)

@doc(
summary: “5 文件上传”
)
@handler uploadFile
post /uploadFile (FileUploadReq) returns (BaseModelJson)

@doc(
summary: “6 文件下载”
)
@handler downloadFile
get /downloadFile (FileShowReq)

@doc(
summary: “7 文件预览”
)
@handler previewFile
get /previewFile (FileShowReq)
}

@server(
group: group2
prefix: /group2
)
service uCenter {
@doc(
summary: “8 登录”
)
@handler login
post /login (UserModel) returns (UserLoginResp)
}

2 api生成api服务命令

go-zero-api\api> goctl api go -api ./doc/ucenter.api -dir ./code

3 代码结构

#查看 目录文件结构
tree /f
#查看 目录结构
tree

目录结构:

└─api
├─code
│ ├─etc
│ └─internal
│ ├─config
│ ├─handler
│ │ ├─group2

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
roup: group2
prefix: /group2
)
service uCenter {
@doc(
summary: “8 登录”
)
@handler login
post /login (UserModel) returns (UserLoginResp)
}

2 api生成api服务命令

go-zero-api\api> goctl api go -api ./doc/ucenter.api -dir ./code

3 代码结构

#查看 目录文件结构
tree /f
#查看 目录结构
tree

目录结构:

└─api
├─code
│ ├─etc
│ └─internal
│ ├─config
│ ├─handler
│ │ ├─group2

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-ObOyWA1Y-1713305979923)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值