Go-Zero定义API实战:探索API语法规范与最佳实践(五)

go,zero,api · 浏览次数 : 0

小编点评

## API语法规范 **基础数据类型:** * `any`:表示任何类型 * `bool`:布尔类型 * `iota`:表示无符号整数类型 * `complex64`、`complex128`、`float32`、`float64`:复数类型 * `int`、`int8`、`int16`、`int32`、`int64`:整数类型 * `rune`:无符号字符类型 * `string`:字符串类型 * `uint`、`uint8`、`uint16`、`uint32`、`uint64`:无符号整数类型 **预定义常量:** * `true`、`false`:布尔常量 * `iota`:无符号整数常量 **预定义函数:** * `append`、`cap`、`close`、`copy`、`delete`、`imag`、`len`、`make`、`new`、`panic`、`print`:常用函数 **分组:** * `group`:用于对服务进行分组的关键字 **示例配置:** ```yaml jwt: AccessSecret: your_secret AccessExpire: 120 ``` **示例代码:** ```go @server @jwt ( prefix :/demo group: demo_api jwt: JwtAuth middleware: Demo_middleware ) // 分组1的服务 service demo-api { @handler DemoHandler post /from (Request) returns (Response) } // 分组2的服务 @server @group (demo_api1) service demo-api { @handler DemoHandler1 get /from/:name(Request) returns (Response) } ```

正文

前言

上一篇文章带你实现了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校验生效了

路由规则

  1. 路由必须以 / 开头 2. 路由节点必须以 / 分隔
  2. 路由节点中可以包含 :,但是 : 必须是路由节点的第一个字符,: 后面的节点值必须要在结请求体中有 path tag 声明,用于接收路由参数,详细规则可参考 路由参数。 4. 路由节点可以包含字母、数字(goctl 1.5.1 支持,可参考 新版 API 解析器使用)、下划线、中划线

参数规则

接收规则 说明 生效范围 示例
json json 序列化 请求体&响应体 json:"foo"
path 路由参数 请求体 path:"id"
form post 请求的表单(支持 content-type 为 form-datax-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语法规范与最佳实践(五)相似的内容:

Go-Zero定义API实战:探索API语法规范与最佳实践(五)

前言 上一篇文章带你实现了Go-Zero模板定制化,本文将继续分享如何使用GO-ZERO进行业务开发。 通过编写API层,我们能够对外进行接口的暴露,因此学习规范的API层编写姿势是很重要的。 通过本文的分享,你将能够学习到Go-Zero的API语法规范,以及学会实际上手使用。 概述 下文所说的是

Go-Zero自定义goctl实战:定制化模板,加速你的微服务开发效率(四)

gozero如何自定义goctl?本文详解和实战,通过本文你将了解goctl的妙用,提高你的开发效率。介绍如何使用goctl工具实现模板定制化,并根据实际项目业务需求进行模板定制化实现。

Go-Zero从0到1实现微服务项目开发(二)

继续更新GoZero微服务实战系列文章:上一篇被GoZero作者万总点赞了,本文将继续使用 Go-zero 提供的工具和组件,从零开始逐步构建一个基本的微服务项目。手把手带你完成:项目初始化+需求分析+表结构设计+api+rpc+goctl+apifox调试+细节处理。带你实现一个完整微服务的开发。

Go-Zero微服务快速入门和最佳实践(一)

前言 并发编程和分布式微服务是我们Gopher升职加薪的关键。 毕竟Go基础很容易搞定,不管你是否有编程经验,都可以比较快速的入门Go语言进行简单项目的开发。 虽说好上手,但是想和别人拉开差距,提高自己的竞争力,搞懂分布式微服务和并发编程还是灰常重要的,这也是我今年更新文章的重点。 更文计划 我会更

Go-Zero技能提升:深度探究goctl的妙用,轻松应对微服务开发挑战!(三)

前言 有位同学在群里说:“Go-Zero官方文档太简洁了,对小白有点不友好。好奇你们是怎么学习的?项目是怎么封装的?有什么提高开发效率的技巧吗?”。 来来来,这期内容给你安排上,先教你goctl的妙用! 前两篇文章分享了 Go-Zero微服务快速入门和最佳实践(一) 和 Go-Zero从0到1实现微

Go微服务开发指南

在这篇深入探讨Go语言在微服务架构中的应用的文章中,我们介绍了选择Go构建微服务的优势、详细分析了主要的Go微服务框架,并探讨了服务发现与注册和API网关的实现及应用。 关注TechLead,复旦博士,分享云服务领域全维度开发技术。拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,复旦机器

Go 使用原始套接字捕获网卡流量

Go 使用原始套接字捕获网卡流量 Go 捕获网卡流量使用最多的库为 github.com/google/gopacket,需要依赖 libpcap 导致必须开启 CGO 才能够进行编译。 为了减少对环境的依赖可以使用原始套接字捕获网卡流量,然后使用 gopacket 的协议解析功能,这样就省去了解析

Go 如何对多个网络命令空间中的端口进行监听

Go 如何对多个网络命令空间中的端口进行监听 需求为 对多个命名空间内的端口进行监听和代理。 刚开始对 netns 的理解不够深刻,以为必须存在一个新的线程然后调用 setns(2) 切换过去,如果有新的 netns 那么需要再新建一个线程切换过去使用,这样带来的问题就是线程数量和 netns 的数

【建议收藏】Go语言关键知识点总结

容器 数组和切片 在Go语言中,数组和切片是两个基本的数据结构,用于存储和操作一组元素。它们有一些相似之处,但也有许多不同之处。下面我们详细介绍数组和切片的特点、用法以及它们之间的区别。 数组 数组是固定长度的序列,存储相同类型的元素。数组的长度在定义时就固定下来,不能改变。 package mai

如何基于R包做GO分析?实现秒出图

GO分析 基因本体论(Gene Ontology, GO)是一个用于描述基因和基因产品属性的标准术语体系。它提供了一个有组织的方式来表示基因在生物体内的各种角色。基因本体论通常从三个层面对基因进行描述:细胞成分(Cellular Component,CC)、生物学过程(Biological Proc