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. 路由节点必须以/
分隔 - 路由节点中可以包含
:
,但是:
必须是路由节点的第一个字符,:
后面的节点值必须要在结请求体中有path
tag 声明,用于接收路由参数,详细规则可参考 路由参数。 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等等.除了上面我们提到 ...
随机推荐
- #二叉堆#JZOJ 4320 旅行
分析 有一个很重要的性质就是如果经过道路数为奇数,把两个点到根节点的路径长加起来就是两个点间的路径长(正负消掉了) 而且众所周知的是奇数+偶数=奇数 可以预处理每个点到根节点的路径长度(按照题目要求) ...
- 使用OHOS SDK构建libjpeg-turbo
参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/libjpeg-turb ...
- 高能有料 | 第二届OpenHarmony技术大会议程速递
第二届开放原子开源基金会OpenHarmony技术大会如约而至 让我们一起 开封无限惊喜的技术成果 开放无限前沿的议题干货 开启无限可能的未来之门 点击此处报名参会!
- C#-GroupBox包含控件,如何获取这些控件的名称
您可以使用 Enumerable.OfType在GroupBox中查找和投射您的RadioButtons: var radioButtons = groupBox1.Controls.OfType&l ...
- centos部署Django一:环境搭建
前言: 参考文档: https://www.cnblogs.com/djangocn/p/9538551.html https://www.icode9.com/content-3-546765.ht ...
- 实战:如何编写一个 OpenTelemetry Extensions
前言 前段时间我们从 SkyWalking 切换到了 OpenTelemetry ,与此同时之前使用 SkyWalking 编写的插件也得转移到 OpenTelemetry 体系下. 我也写了相关介绍 ...
- 分布式文件存储-FastDFS
1.1 FastDFS简介 1.1.1 FastDFS体系结构 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了 ...
- git默认忽略文件名称大小写
0. 现象 当将文件名称test 修改为 Test时,git提交记录检测不到变化 1.原因 Git默认设置忽略文件名大小写是因为不同操作系统对文件名大小写的处理方式不同,为了避免在不同操作系统之间出现 ...
- 力扣220(java)-存在重复元素 III(困难)
题目: 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i ...
- Elastic与阿里云助力汽车及出行产业数字化转型
简介:目前,阿里云和Elastic在全国已经有很多的项目正在开展合作,而在移动出行领域与享道出行的合作案例,则是代表性的. 在汽车产业变革逐步深入的当下,云计算.大数据等信息技术成为了汽车企业经历数 ...