Go-Zero定义API实战:探索API语法规范与最佳实践(五)
前言
上一篇文章带你实现了Go-Zero模板定制化,本文将继续分享如何使用GO-ZERO进行业务开发。
通过编写API层,我们能够对外进行接口的暴露,因此学习规范的API层编写姿势是很重要的。
通过本文的分享,你将能够学习到Go-Zero的API语法规范,以及学会实际上手使用。
概述
下文所说的是 api 是 go-zero 自研的领域特性语言(下文称 api 语言 或 api 描述语言),旨在实现人性化的基础描述语言,作为生成 HTTP 服务最基本的描述语言。
api 领域特性语言包含语法版本、info 块、结构体声明、服务描述等几大块语法组成,其中结构体和 Golang 结构体 语法几乎一样,只是移除了 struct 关键字。
实战前准备
首先需要你在本地安装goctl、go-zero,下载教学和地址点击这里,按照教程操作即可,非常简单。
下面按顺序和我操作吧,对使用模板快速生成API层不清楚的同学务必先看我前篇文章:Go-Zero goctl实战
这里我假设你已经创建好了一个API服务的demo,且目录结构长这样:

学习API语法
对于Go语言开发者来说,Go-Zero的API语法学习和理解成本极低,我们可以很轻松的学会API语法。下面我会为大家介绍重点需要掌握的语法。更详细的语法规范,可以参考官网:API 规范 | go-zero Documentation
生成API文件
cd demo
goctl api go -api demo.api -dir . -style gozero
- 基础的API文件

ID标识符
golang中的预定义类型、常量、函数,以及关键字在api里面同样适用
- 预定义
//预定义类型:
any bool byte comparable
complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr
//预定义常量:
true false iota
//零值:
nil
//预定义函数:
append cap close complex copy delete imag len
make new panic print println real recover
- 关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
tip:需要注意的是 goctl api不支持any类型!!!
类型声明
规则
- 类型声明必须以
type开头 - 不需要声明
struct关键字 - 不支持嵌套结构体声明
- 不支持别名
示例
type StructureExample {
// 基本数据类型示例
BaseInt int `json:"base_int"`
BaseBool bool `json:"base_bool"`
BaseString string `json:"base_string"`
BaseByte byte `json:"base_byte"`
BaseFloat32 float32 `json:"base_float32"`
BaseFloat64 float64 `json:"base_float64"`
// 切片示例
BaseIntSlice []int `json:"base_int_slice"`
BaseBoolSlice []bool `json:"base_bool_slice"`
BaseStringSlice []string `json:"base_string_slice"`
BaseByteSlice []byte `json:"base_byte_slice"`
BaseFloat32Slice []float32 `json:"base_float32_slice"`
BaseFloat64Slice []float64 `json:"base_float64_slice"`
// map 示例
BaseMapIntString map[int]string `json:"base_map_int_string"`
BaseMapStringInt map[string]int `json:"base_map_string_int"`
BaseMapStringStruct map[string]*StructureExample `json:"base_map_string_struct"`
BaseMapStringIntArray map[string][]int `json:"base_map_string_int_array"`
// 匿名示例
*Base
// 指针示例
Base4 *Base `json:"base4"`
// 新的特性( goctl >= 1.5.1 版本支持 )
// 标签忽略示例
TagOmit string
}
路由前缀
我们可以通过prefix关键字区分路由组

接着再使用goctl api生成代码以及swagger,将swagger导入apifox查看路由前缀,可以看见就增添了前缀/demo。
不知道怎么生成api代码的同学可以看我往期的gozero实战分享——go-zero goctl实战

服务分组
当我们的业务体量上来后,服务接口也会越来越多,生成的代码文件(handler、logic文件等)也会越来越多。这时候我们就需要对不同的接口按一定的分组进行区分,用文件夹进行隔离,以便于开发和维护。
- 分组前的目录结构是这样的

- 我们先将生成的handler和logic文件删除。
- 只需要在@server语句块里面添加关键字group就能进行分组。分组后的结构如下图所示。

JWT校验
- 接下来我们再来看一下api文件中怎么开启jwt认证
- 在配置文件demo-api.yaml中添加jwt配置

- 在config文件中添加一个JWT认证需要的密钥和过期时间配置
JwtAuth struct { // JWT 认证需要的密钥和过期时间配置
AccessSecret string
AccessExpire int64
}

- 使用方法也很简单,我们在@service语句块中添加jwt关键字,使用Auth即可开启jwt。

- 通过测试请求我们可以看见返回401没有权限,说明jwt校验生效了

路由规则
- 路由必须以
/开头 2. 路由节点必须以/分隔 - 路由节点中可以包含
:,但是:必须是路由节点的第一个字符,:后面的节点值必须要在结请求体中有pathtag 声明,用于接收路由参数,详细规则可参考 路由参数。 4. 路由节点可以包含字母、数字(goctl 1.5.1支持,可参考新版 API 解析器使用)、下划线、中划线
参数规则
| 接收规则 | 说明 | 生效范围 | 示例 |
|---|---|---|---|
| json | json 序列化 | 请求体&响应体 | json:"foo" |
| path | 路由参数 | 请求体 | path:"id" |
| form | post 请求的表单(支持 content-type 为 form-data 和 x-www-form-urlencoded) 参数请求接收标识,get 请求的 query 参数接收标识 |
请求体 | form:"name" |
| header | http 请求体接收标识 | 请求体 | header:"Content-Length" |
中间件声明
- 想要使用中间件,可以在@server语句块中使用关键字middleware生成一个中间件模板。
- TIP:需要注意的是中间件首字母必须大写,否则无法被其他包导入。

- 在svc包的servicecontext.go中注册中间件

- 生成的中间件代码如下

API Import
- 当我们的业务体量上来后,api文件可能会越来越大,又或者我们有一些公共结构体。如果我们都写在同一个api文件中,那么api文件将会变得非常巨大,不易阅读和维护,这时候就需要拆解api文件,通过import来导入。
syntax
- 版本信息,import中的版本信息必须与被import的api版本信息一样。
- 规范写法
syntax = "v1"
- 我们创建一个新的文件demo1.api,并且将分组而写到这个api文件下。
- 因为我们的请求体和响应体是公共结构体,都写在demo.api下面了,我们通过import "demo.api"就能导入demo.api。

完整的api文件模板
syntax = "v1"
type Request {
Name string `path:"name,options=you|me"`
}
type Response {
Message string `json:"message"`
}
@server (
prefix :/demo
group: demo_api
jwt: JwtAuth
middleware: Demo_middleware
)
// 分组1的服务
service demo-api {
@handler DemoHandler
post /from (Request) returns (Response)
}
// 分组2的服务
@server (
prefix :/demo1
group: demo_api1
)
service demo-api {
@handler DemoHandler1
get /from/:name(Request) returns (Response)
}
总结
这篇文章详细介绍了如何使用Go-Zero进行API的定义,并进行了实际演示。希望对你有帮助。
我将继续更新Go-Zero系列文章,如果你对Go语言或者微服务感兴趣,欢迎关注我,也欢迎直接私信我。
Go-Zero定义API实战:探索API语法规范与最佳实践(五)的更多相关文章
- paip.复制文件 文件操作 api的设计uapi java python php 最佳实践
paip.复制文件 文件操作 api的设计uapi java python php 最佳实践 =====uapi copy() =====java的无,要自己写... ====php copy ...
- 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践
本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主.主要NuGet包:无 一.创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点 1 //定义Person类 ...
- 构建你的长寿命的API第1部分:规范驱动的API开发
构建你的长寿命的API第1部分:规范驱动的API开发 这篇文章是由MuleSoft的Mike Stowe在nginx.conf 2016公布的演示文稿改编的.第一部分重点是规范驱动的API开发. 第二 ...
- 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信
官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...
- Kafka之 API实战
Kafka之 API实战 一.环境准备 1)启动zk和kafka集群,在kafka集群中打开一个消费者 [hadoop1 kafka]$ bin/kafka-console-consumer.sh \ ...
- 百度AI开放平台- API实战调用
百度AI开放平台- API实战调用 一. 前言 首先说一下项目需求. 两个用户,分别上传了两段不同的文字,要计算两段文字相似度有多少,匹配数据库中的符合条件的数据,初步估计列出来会有60-1 ...
- 集合 数组 定义 转换 遍历 Arrays API MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- (转)RESTful API 设计最佳实践
原文:http://www.oschina.net/translate/best-practices-for-a-pragmatic-restful-api 数据模型已经稳定,接下来你可能需要为web ...
- lumen 构建api(dingo api)
什么是 API API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力, ...
- HTML5之本地文件系统API - File System API
HTML5之本地文件系统API - File System API 新的HTML5标准给我们带来了大量的新特性和惊喜,例如,画图的画布Canvas,多媒体的audio和video等等.除了上面我们提到 ...
随机推荐
- VS的 x86_64 , x64_86 , x64 , x86 有什么区别
x86 Native Tools Command Prompt - Sets the environment to use 32-bit, x86-native tools to build 32-b ...
- Git分支教程:详解分支创建、合并、删除等操作
Git是一种强大的分布式版本控制系统,它的分支功能使得团队协作和代码管理变得更加灵活和高效.分支可以让开发人员在不影响主线开发的情况下进行并行开发和实验性工作.本篇博客将详解Git分支的创建.合并.删 ...
- 初学STM32 SDIO(一)
1. SDIO协议简介 SDIO全称是安全数字输入/输出接口 ,控制器对SD卡进行读写通信操作一般有两种通信接口可选,一种是SPI接口,另外一种就是SDIO接口. 多媒体卡(MMC).SD卡. S ...
- HMS Core打造影音娱乐行业解决方案,助推视听新浪潮
6月28日,HDD·HMS Core. Sparkle影音娱乐线上沙龙在各大直播平台与开发者们见面.本次线上沙龙围绕影音娱乐行业现状观察和趋势.用户数据洞察分析以及HMS Core影音娱乐行业解决方案 ...
- linux打包Qt,收集依赖库脚本
编写shell脚本,用来收集Qt的依赖库,避免在无环境裸机上无法运行 1.创建shell脚本:touch pack.sh 2.编辑shell脚本,脚本内容如下:vi pack.sh 3.给脚本增加权限 ...
- openGauss数据库xlog目录满问题处理
openGauss 数据库 xlog 目录满问题处理 openGauss 数据库 xlog 满通常为以下几个原因: 1.主备状态不正常,存在网络问题,集群内有宕机的节点 2.xlog 保留数量过多 3 ...
- HarmonyOS—使用Web组件加载页面
页面加载是Web组件的基本功能.根据页面加载数据来源可以分为三种常用场景,包括加载网络页面.加载本地页面.加载HTML格式的富文本数据. 页面加载过程中,若涉及网络资源获取,需要配置ohos.pe ...
- CPVT:美团提出动态位置编码,让ViT的输入更灵活 | ICLR 2023
论文提出了一种新的ViT位置编码CPE,基于每个token的局部邻域信息动态地生成对应位置编码.CPE由卷积实现,使得模型融合CNN和Transfomer的优点,不仅可以处理较长的输入序列,也可以在视 ...
- GaussDB(DWS)基于Flink的实时数仓构建
本文分享自华为云社区<GaussDB(DWS)基于Flink的实时数仓构建>,作者:胡辣汤. 大数据时代,厂商对实时数据分析的诉求越来越强烈,数据分析时效从T+1时效趋向于T+0时效,为了 ...
- 存储过程编写·记(“xxx“在需要下列之一:if)
存储过程编写·记("xxx"在需要下列之一:if) 使用的数据库为Oracle数据库,数据库客户端为DBeaver 简单来说,就是使用SQL语句进行一些函数编写,进而进行一些过滤啊 ...