go-zero 实战(4)

中间件

在 userapi 项目中引入中间件。go项目中的中间可以处理请求之前和之后的逻辑。

1. 在 userapi/internal目录先创建 middlewares目录,并创建 user.go文件

package middlewaresimport ("github.com/zeromicro/go-zero/core/logx""net/http"
)type UserMiddleware struct {
}func NewUserMiddleware() *UserMiddleware {return &UserMiddleware{}
}func (*UserMiddleware) LoginAndReg(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("execute before login and register")next(w, r)logx.Info("execute after login and register")}
}

这里,就定义了一个中间件。

2. 在 userapi/internal/svc/servicecontext.go 文件中创建一个中间件实例

package svcimport ("github.com/zeromicro/go-zero/zrpc""rpc-common/userclient""userapi/internal/middlewares""userapi/internal/config"
)type ServiceContext struct {Config         config.ConfigUserRpc        userclient.UserUserMiddleware *middlewares.UserMiddleware // 定义中间件
}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config:         c,UserRpc:        userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),UserMiddleware: middlewares.NewUserMiddleware(), // 创建中间件实例}
}

3. 修改 userapi/internal/handler/routers.go 文件

在这里插入图片描述
在这里引入了路由中间件。

4. 修改 userapi/internal/logic/userapilogic.go文件

在该文件中,修改 Login 方法,加入一行日志。为了后面测试用。

func (l *UserLogic) Login(t *types.LoginRequest) (string, error) {logx.Info("login executing....")  // 新加入的代码userId := 100auth := l.svcCtx.Config.Authreturn l.getToken(auth.AccessSecret, time.Now().Unix(), auth.AccessExpire, userId)
}

5. 测试中间件

在这里插入图片描述
访问 login 接口后,在控制台打印日志。日志是由路由中间件打印的。

6. 全局中间件

上面引入的路由中间件是,可以针对部分路由起作用,如果想要对所有路由起作用,可以使用全局中间件。
在 userapi/internal/handler/routers.go文中,加入一行代码:
在这里插入图片描述
这样引入的中间件,就是全局中间件,对所有路由都会生效。

自定义错误

1. 引出问题

  1. 在 userapi/internal/logic/userapilogic.go 文件的 GetUser 方法加一段逻辑
    在这里插入图片描述
  2. 测试
    在这里插入图片描述
    用postman 测试后,结果如图。显然,很多情况下,我们不想直接获取到这种形式的错误。更愿意拿到一个 json 格式的错误,包括错误代码,错误内容。这样更容易处理。

2. 在 userapi/internal 创建 errorx 目录,来管理错误

在 userapi/internal/errorx 目录创建一个 error.go 文件

package errorxvar ParamsError = New(1101, "parameter error")type BizError struct {Code int    `json:"code"`Msg  string `json:"msg"`
}func New(code int, msg string) *BizError {return &BizError{Code: code,Msg:  msg,}
}func (e *BizError) Error() string {return e.Msg
}type ErrorResponse struct {Code int    `json:"code"`Msg  string `json:"msg"`
}func (e *BizError) Data() *ErrorResponse {return &ErrorResponse{e.Code,e.Msg,}
}

该文件定义了错误码和错误内容。

3. 修改 userapi/internal/logic/userapilogic.go 文件

在这里插入图片描述
返回错误的时候,返回我们上一步自定义的错误。

4. 修改 userapi/userapi.go 文件,增加错误处理逻辑

在这里插入图片描述
增加了,错误处理的逻辑。

5. 测试

在这里插入图片描述
这样,就获取到 json 格式的错误数据。

goctl 命令

1. 源码文件生成格式

goctl api go -api userapi.api -dir ./gen 

这种方式生成的代码,文件名称是所有字母全小写。有时候我们需要不同的命名格式,比如有些团队或个人喜欢驼峰命名方式,有些喜欢snake的形式

goctl api go -api userapi.api -dir ./gen -style go_zero 

这种方式生成的文件名称是 snake 形式。

goctl api go -api userapi.api -dir ./gen -style goZero 

这种命名方式是驼峰命名方式

2. 生成 proto 文件

goctl rpc template -o=user.proto

利用模板生成 .proto 文件,这样在开发过程中,有一个基础模块。在这个目标上进行修改,相对更方便一点。

3. 生成 rpc 服务代码

goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.

之前,我们项目的代码就是靠这种方式生成的。

4. 生成 model 代码

goctl model mysql ddl -src="./*.sql" =dir="./sql/model" -c

根据数据库的 ddl 语句,生成模型代码。生成的这部分代码,可以摘取部分使用,减少工作量。

5. 生成 dockerfile

goctl docker -go hello.go

hello.go 是启动类。

6. 生成 k8s 只要清单

goctl kube deploy -name redis -namespace adhoc -image redis:6-alpine -o redis.yaml -port 6379

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

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

相关文章

经济寒冬下的黄金跳板:方案、活动、竞标一手掌握

推荐策划人必备的宝藏地产策划资源平台, 订阅浩叫:地产营销策划圈。这个平台简直是地产策划人的百宝箱,里面藏着无数的策划秘籍,等着你来挖掘。 这个平台就像是一个大型的方案库,里面收录了众多知名地产企业的内部资料…

leetcode:计数质数

class Solution { public:// 如果 x 是质数&#xff0c;那么大于 x 的 x 的倍数 2x,3x… 一定不是质数int countPrimes(int n) {vector<int> isPrime(n, 1);int ans 0;for (int i 2; i < n; i) {if (isPrime[i]) {ans 1;if ((long long)i * i < n) {for (int j …

leetcode-55 跳跃游戏

leetcode Problem: 55. 跳跃游戏 思路 假设我们是一个小人&#xff0c;从第一个下标开始&#xff0c;每次经过一个位置&#xff0c;我们就可以根据当前位置的数值nums[i]和位置下标i计算出该位置所能到达的后续位置的最大值rnums[i]i。而这个r之前的区域一定都是可以经过的。…

AI 谈“浔川AI翻译机”

在天工AI&#xff0c;天工AI在全网搜索“浔川AI翻译机”。 1 创作助手谈“浔川AI翻译机”&#xff1a; “浔川AI翻译机”是一个利用人工智能技术进行语言翻译的设备或应用程序。它可以将一种语言的文字或口语翻译成另一种语言&#xff0c;以实现不同语言之间的沟通和理解。浔…

Linux指令初识

ls:显示当前目录底下的指定文件或目录 ls -l更详细的信息 ls -a显示当前目录下的所有文件 命令中的选项可以一次传递多个 ,例如&#xff1a;ls -al 命令和选项有必须一个或多个空格 以.开头的文件&#xff0c;为隐藏文件ls -a可以看到,ls -l看不见 支持命令拼在一起&#…

牛客热题:滑动窗口的最大值

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;滑动窗口的最大值题目链接方法一…

DNS服务的部署与配置(2)

1、dns的安装及开启 dnf install bind.x86_64 -y #安装 #Berkeley Internet Name Domain (BIND) systemctl enable --now named #启用dns服务&#xff0c;服务名称叫named firewall-cmd --permanent --add-servicedns #火墙设置 firewall-cmd --reload …

【手把手搓组件库】从零开始实现Element Plus--组件开发

从零开始实现Element Plus--组件开发 nvmnvm的作用&#xff1a;nvm的使用方法 需求分析提示词Kimi 生成产品需求文档kimi 生成测试用例 初始化 vitest完善 Button 组件1、定义 types.ts2、Button.vue 引入 types.ts3、添加Button样式点击事件 添加节流添加 Icon 集成 StoryBook…

C++第十九弹---string模拟实现(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、修改操作 2、迭代器操作 3、字符串操作 4、非成员函数重载操作 总结 1、修改操作 1、string& operator (const char* s); //尾部插入…

【Text2SQL 论文】SeaD:使用 Schema-aware 去噪训练的 end2end 的 Text2SQL

论文&#xff1a;SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising ⭐⭐ NAACL 2022, arXiv:2105.07911 本论文提出 SeaD 模型&#xff0c;使用 schema-aware 的去噪方法来训练一个 end2end、seq2seq 的 Transformer 模型来实现 Text2SQL。 一、论文速读…

C++系列-static成员

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 概念 声明为static的类成员称为类的静态成员&#xff0c;用static修饰的成员变量&#xff0c;称之为静态成员变量&#xff0c;用static修饰的成员函数&#xff0c;称之为静态成…

stm32学习-流水灯

接线 注意&#xff1a;LED灯长一点的引脚是正极。 配置GPIO 1.使用RCC开启GPIO时钟 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_APB1Perip…

【Qt 学习笔记】Qt窗口 | 菜单栏 | QMenuBar的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | 菜单栏 | QMenuBar的使用及说明 文章编号&#xff1a;Qt 学习…

第20届文博会:“特别呈现”—周瑛瑾雷米·艾融双个展,著名美术评论家,批评家彭德教授对周瑛瑾作品进行评论

周瑛瑾不是学院派艺术家&#xff0c;但在彩墨画领域的天赋超出中国八大美院的同类型画家。相比具有批判意识的当代艺术&#xff0c;他的彩墨艺术如同我们这个苦难世界的创可贴和安慰剂。当我面对他的彩墨画&#xff0c;首先是惊艳&#xff0c;随之想到屈原的离骚&#xff0c;还…

[CISCN 2024] Crypto部分复现

文章目录 OvOez_rsacheckin浅记一下 迟来的文章 OvO 题目描述&#xff1a; from Crypto.Util.number import * from secret import flagnbits 512 p getPrime(nbits) q getPrime(nbits) n p * q phi (p-1) * (q-1) while True:kk getPrime(128)rr kk 2e 65537 kk …

【三维修复、分割与编辑】InFusion、Bootstrap 3D、GaussianGrouping、GaussianEditor等(论文总结)

提示&#xff1a; 文章目录 前言一、InFusion&#xff1a;扩散模型助力&#xff0c;效率提高20倍&#xff01;(2024)1. 摘要2. 算法3. 效果 二、2D Gaussian Splatting三、Bootstrap 3D:从扩散模型引导三维重建1.摘要2.相关工作3.方法1.Boostrapping by Diffusion 通过扩散模型…

学习存储协议的利器,聊聊tcpdump和Wireshark

数据存储技术分为多个方面,包括数据持久化、数据映射、数据压缩和通信协议等等。其中通信协议是数据存储技术中非常重要的一部分,正是通信协议使得计算节点可以访问存储设备。同时,也正是不同的协议让存储系统呈现不同的形态。 如下图所示,通过iSCSI协议,可以将存储端的存…

【JVM实践与应用】

JVM实践与应用 1.类加载器(加载、连接、初始化)1.1 类加载要完成的功能1.2 加载类的方式1.3 类加载器1.4 双亲委派模型1.5自定义ClassLoader1.6 破坏双亲委派模型2.1 类连接主要验证内容2.2 类连接中的解析2.3 类的初始化3.1 类的初始化时机3.2 类的初始化机制和顺序3.2 类的卸…

C从零开始实现贪吃蛇大作战

个人主页&#xff1a;星纭-CSDN博客 系列文章专栏 : C语言 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 有关Win32API的知识点在上一篇文章&#xff1a; 目录 一.地图 1.控制台基本介绍 2.宽字符 1.本地化 2.类项 3.setlocale函…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…