Go-zero(api部分)

news2024/11/16 21:54:32

目录

api的语法:

type:用于定义请求/响应体

service:定义HTTP服务

@server:控制生成HTTP服务时候的meta信息

根据api文档生成最小HTTP服务

目录结构

api响应封装


api的语法:

首先定义一个api文档

type:用于定义请求/响应体
type LoginRequest {
	Username string `json:"username"`
	Password string `json:"password"`
}

type UserInfoResponse {
	UserId   uint   `json:"userId"`
	Username string `json:"username"`
}

其中LoginRequest表示登录的请求体,要求包含string类型的username和password

语法类似于go的type struct

也支持写在一起

type(
	LoginRequest {
		Username string `json:"username"`
		Password string `json:"password"`
	}
	 UserInfoResponse {
		UserId   uint   `json:"userId"`
		Username string `json:"username"`
	}
)

效果是一样的

service:定义HTTP服务
service users {
	@handler login
	post /login (LoginRequest) returns (string)
}

service users表示定义了一个名称为users的微服务,最后的入口文件名称也会是users.go

@handler 用于对生成的文件和方法命名

post /login (LoginRequest) returns (string)

  • post:表示这是一个post请求
  • /login:表示请求路由
  • (Request) returns (Response) 表示根据Request请求体,返回响应体Response,样例中的就是根据LoginRequest登录请求体返回一个字符串,当然这个后面也是可以自定义的,也可以不需要请求体,写法就是这样post /login  returns (string)
@server:控制生成HTTP服务时候的meta信息
@server (
	prefix: /api/users
	jwt:    Auth
)

比如说prefix: /api/users 对该定义后面的services都加上路由前缀/api/users

jwt: Auth用于jwt鉴权(目前自己测试使用只成功了token的创建,token解析还没有成功)

目前支持的功能

  1. 路由分组
  2. 中间件声明
  3. 路由前缀
  4. 超时配置
  5. jwt 鉴权开关

如果需要对多个服务设置不同的meta信息

则可以这样写

type(
	LoginRequest {
		Username string `json:"username"`
		Password string `json:"password"`
	}
	 UserInfoResponse {
		UserId   uint   `json:"userId"`
		Username string `json:"username"`
	}
)

@server (
	prefix: /api/users
)
service users {
	@handler login
	post /login (LoginRequest) returns (string)
}

@server (
	prefix: /api/users
	jwt:    Auth
)
service users {
	@handler userInfo
	get /info returns (UserInfoResponse)
}

//goctl api go -api user.api -dir .

第一个server管理login服务

第二个server管理userInfo服务

根据api文档生成最小HTTP服务

生成代码:

goctl api go -api user.api -dir .

goctl为关键字。api go,表示根据api文档生成go文档,-api用于指定api文件的位置这里的位置为(当前目录下的user.api文件,-dir用于指定go文档的生成位置,"."表示在当前目录下生成

目录结构

最终会在指定位置生成这样一个目录结构:

从上到下一个一个解释的话:

  • etc/user.yaml:用来保存基础的配置文件服务名称,主机地址,以及端口号
  • internal/config/config.go:主要用于加载保存user.yaml中的的数据以供使用
  • hander/loginhandler.go:用于处理login请求,过程大概就是下面这样的
func loginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		//提取请求中保存的请求体,如果没有相应的请求体数据,则返回错误信息
		var req types.LoginRequest
		if err := httpx.Parse(r, &req); err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
			return
		}

		//调用请求处理函数,返回响应结果
		l := logic.NewLoginLogic(r.Context(), svcCtx)
		resp, err := l.Login(&req)
		//根据响应结果返回响应数据
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, resp)
		}
	}
}
  • handler/router.go:主要保存路由信息
  • logic/loginlogic.go和logic/userinfologic:数据处理函数,供handler中的方法调用
  • svc/servicontext.go:返回一个携带配置信息的上下文
  • types/types.go:用于存放实体类
  • user.go:程序入口

整体的一个运行流程差不多为:

从user.go开始读取users.yaml配置文件,并将内保存到config.go文件中

根据handler/routers.go中的路由加载路由配置,然后启动服务

接受到对应的请求后就会调用handler中对应的方法,handler会调用logic的具体处理业务,处理完成后返回处理结果,并响应数据

因此对数据的一些特殊处理也都可以在handler中实现

api响应封装

将所有的响应都封装为一个统一的格式

func Response(r *http.Request, w http.ResponseWriter, res any, err error) {
	body := Body{}
	if err != nil {
		body = Body{
			Code: 10086,
			Data: nil,
			Msg:  "请求错误",
		}
	} else {
		body = Body{
			Code: 10086,
			Data: res,
			Msg:  "请求成功",
		}
	}
	//func WriteJson(w http.ResponseWriter, code int, v any)
	//将数据v写入到响应体response中
	httpx.WriteJson(w, http.StatusOK, body)

}

就可以自己写好一个Response方法,然后插入到handler方法中

func loginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		//提取请求中保存的请求体,如果没有相应的请求体数据,则返回错误信息
		var req types.LoginRequest
		if err := httpx.Parse(r, &req); err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
			return
		}

		//调用请求处理函数,返回响应结果
		l := logic.NewLoginLogic(r.Context(), svcCtx)
		resp, err := l.Login(&req)
		
		
		response.Response(r, w, resp, err)
		
		
		//根据响应结果返回响应数据
		//if err != nil {
		//	httpx.ErrorCtx(r.Context(), w, err)
		//} else {
		//	httpx.OkJsonCtx(r.Context(), w, resp)
		//}
	}
}

唯一麻烦的就是需要一个一个去加

官方本身也提供了一个这样的封装

type (
	Response {
		Code int    `json:"code"`
		Msg  string `json:"msg"`
	}
)

type (
	UserInfo {
		UserId   uint   `json:"userId"`
		Username string `json:"username"`
	}
)

type (
	UserInfoResponse {
		Response
		Data UserInfo `json:"data"`
	}
)

写的结构和最终生成的实体类的结构也是一样的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电磁兼容(EMC):时钟电路PCB设计

目录 1. 布局 2. 布线 时钟电路做为产品内部的强辐射源,在设计阶段已经选用展频或者分频方案后,见另外接下来就需要对PCB的耦合路径进行规划设计。时钟电路具体的PCB设计具体要求如下: 1. 布局 结构干涉:时钟电路的晶振和法拉电…

K8s之ku-be admin部署安装

目录 一、环境配置 1、机器部署 2、部署大致流程 二、实验环境配置 1、所有节点关闭防火墙核心防护以及关闭swap交换 2、所有节点安装docker 3、所有节点安装kubeadm,kubelet和kubectl 4、部署K8s集群 5、设定kubectl 6、所有节点部署网络插件flannel 7、…

身份证实名认证API接口对接流程

该接口传入姓名、身份证号,核验二要素是否一致,返回生日、性别、籍贯等信息。 应用于各类线上平台和服务的身份认证验证,以保障用户信息的真实性和交易的安全性。 首先找到提供接口的平台供应商,注册账号后获取免费套餐&#xff…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-16讲 EPIT定时器

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Php composer 基础教程

一、什么是Composer? Composer 是 PHP 中的依赖管理工具。它允许声明项目所依赖的库,并且它将为您管理(安装/更新)它们。 二、如何安装? Linux 系统和 MacOS 系统 直接下载最新稳定版: 然后执行下列命令&…

nss刷题(关于ssti)

1、[HNCTF 2022 WEEK2]ez_SSTI 首先是注入${7*7}没有回显出49的情况,再次注入{{7*7}}如果还是没有回显49就代表这里没有模板注入;如果注入{{7*7}}回显了49代表执行成功,继续往下走注入{{7*7}},如果执行成功回显7777777…

图生代码,从Hello Onion 代码开始

从Hello Onion 代码开始 1,从代码开始 原生语言采用java 作为载体。通过注解方式实现“UI可视化元素"与代码bean之间的映射. 转换示例 2,运行解析原理 在执行JAVA代码期间,通过读取注解信息,转换为前端的JSON交由前端JS框…

【linux性能分析】perf分析CPU占用详情

文章目录 1. 如何使用perf工具1.1 perf安装1.2 首次使用perf报错1.3 添加测试程序1.4 编译并执行指令生成perf.data文件1.5 添加-g选项能查看call graph调用信息1.6 查看perf.data1.7 perf工作流1.8 sudo perf record -F 99 -p 2512 -g -- sleep 60 2. 如何生成火焰图2.1 安装火…

技术前沿 |【自回归视觉模型ImageGPT】

自回归视觉模型ImageGPT 引言一、ImageGPT的基本原理与创新之处二、ImageGPT在图像生成、理解等视觉任务上的应用三、ImageGPT对后续视觉Transformer模型发展的影响四、ImageGPT的深入应用 引言 在人工智能的飞速发展中,视觉模型作为其中一个重要的分支&#xff0c…

Qt运行时,如何设置第一个聚焦的控件

问题:Qt第一个聚焦的控件,如何自行设置? 尝试: 1.在代码中设置 lineEdit->setFocus() 。无效! 2.Qt Designer–打开form1.ui–菜单栏下一行–Edit Tab Order–按顺序点击–菜单栏下一行–Edit Widgets–退出。无效…

JDBC、datasource、数据库驱动、持久层框架之间的区别

1、jdbc Java Database Connectivity(JDBC)是Java平台下的一个标准API,它定义了一组用于连接各种数据库系统、执行SQL语句和处理结果集的接口和类。使用JDBC API,开发人员可以编写能够访问不同数据库系统的应用程序,而…

react组件传参 父传子可以传字符串,布尔值,数组,对象,jsx,

在react中&#xff0c;父传子组件 props的灵活性是很强大的&#xff0c;可以传字符串&#xff0c;布尔值&#xff0c;数组&#xff0c;对象&#xff0c;jsx&#xff0c; function Son(props) {console.log(props,"props的值")return(<div>这是儿子组件 {props.…

论文精读-SRFormer Permuted Self-Attention for Single Image Super-Resolution

论文精读-SRFormer: Permuted Self-Attention for Single Image Super-Resolution SRFormer:用于单图像超分辨率的排列自注意 Params&#xff1a;853K&#xff0c;MACs&#xff1a;236G 优点&#xff1a; 1、参考SwinIR的RSTB提出了新的网络块结构PAB&#xff08;排列自注意力…

非授权人员进入报警系统

非授权人员进入报警系统基于智能视频分析技术和深度学习技术&#xff0c;非授权人员进入报警系统通过现场已经装好的监控摄像头针对人体进行精准检测&#xff0c;并根据设置的禁入区范围进行判断。通过图像处理和人体识别算法&#xff0c;非授权人员进入报警系统可以在实时监测…

适用于当下的红色系统可视化大屏,大量图。

特定场合下使用红色系可视化大屏是可以的&#xff0c;但是千万要注意时间和场合&#xff0c;平时最好别用。

【Linux系统】文件与基础IO

本篇博客整理了文件与文件系统、文件与IO的相关知识&#xff0c;借由库函数、系统调用、硬件之间的交互、操作系统管理文件的手段等&#xff0c;旨在让读者更深刻地理解“Linux下一切皆文件”。 【Tips】文件的基本认识 文件 内容 属性。文件在创建时就有基本属性&#xff0…

简单快捷的图片格式转换工具:认识webp2jpg-online

经常写博客或记笔记的朋友们可能会碰到图床不支持的图片格式或图片太大需要压缩的情况。通常&#xff0c;我们会在浏览器中搜索在线图片格式转换器&#xff0c;但这些转换器往往伴有烦人的广告或要求登录&#xff0c;并且支持的转换格式有限。最近&#xff0c;我在浏览 GitHub …

【董晓算法】竞赛常用知识之图论2(最小环,最小生成树)

前言&#xff1a; 本系列是学习了董晓老师所讲的知识点做的笔记 董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com) 动态规划系列&#xff08;还没学完&#xff09; 【董晓算法】动态规划之线性DP问题-CSDN博客 【董晓算法】动态规划之背包DP问题&#xff…

AI交互数字人讲解员对博物馆有何价值?

近日&#xff0c;贵州省地质博物馆推出AI交互数字人贵州龙“贵贵”&#xff0c;采用垂直类大语言模型驱动&#xff0c;拥有贵地博相关专业知识&#xff0c;能够作为数字人讲解员向公众解答关于博物馆的各类问题。该AI交互数字人身着考古服装、佩戴馆徽、以可爱的小龙形象&#…

vue使用driver.js引导并自定义样式和按钮

参考网址https://driverjs.com/docs/installation 安装 npm install driver.js 以下是1.3.1版本的基本使用方法 import { driver } from driver.js import driver.js/dist/driver.css mounted() {// 实例化driver对象const driverObj driver({showProgress: true,steps: …