GoZero微服务个人探究之路(七)添加中间件、自定义中间件

2024-01-21 07:44

本文主要是介绍GoZero微服务个人探究之路(七)添加中间件、自定义中间件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说在前面

官方已经自己实现了很多中间件,我们可以方便的直接使用,不用重复造轮子了

开启方式可以看官方文档

中间件 | go-zero Documentation

实现自定义的中间件

在业务逻辑中,我们需要实现自定义功能的中间件

------这里我们以实现跨源访问的中间件(详情可见这篇文章flutter开发web应用网络请求后台失败--记录遇到的跨源资源共享问题-CSDN博客)

与我的实现不同也没关系,方式都是通的,相似的

方案一 官方文档方案

server := rest.MustNewServer(rest.RestConf{})
defer server.Stop()server.Use(middleware)// 自定义的中间件
func middleware(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {w.Header().Add("X-Middleware", "static-middleware")next(w, r)}
}

这里我们可以看到,官方是在启动文件里面加了server.Use(middleware)这一行,并且以函数方式实现了中间件,但这样的方式不利于低耦合,但是十分有借鉴意义

方案二 中间件写在另外的文件里

这里我们在internal包里新建一个middleware文件夹用于专门存放中间件代码,

这里我定义了一个corsmiddleware.go

中间的代码根据个人情况而定,编写符合自己逻辑的代码

之后在servicecontext.go里面,也就是生产svc context的文件里面,

  1. ServiceContext结构体内添加Cors rest.Middleware
  2. NewServiceContext函数添加corsMiddleware := middleware.CorsMiddleware

  3. return &ServiceContext的结构体内添加Cors: corsMiddleware,

最后就可以在启动文件内,调用server.Use(ctx.Cors)了,这样我们的中间件就被加上了


另外---->我们采用的是goZero的rest包的rest.Middleware

其定义为:Middleware func(next http.HandlerFunc) http.HandlerFunc

这是一个标准的中间件结构,接受一个handlerfunc,返回另外一个handlerfunc,但是涉及到更复杂的逻辑就不够用了

补充

这里我们以一个更复杂的中间件为例:

需要接受一个redis客户端实例,从redis中获取用户可以访问的url列表


先定义中间件结构体

type CheckUrlMiddleware struct {Redis *redis.Redis
}

其中包含了指向redis客户端的指针

再定一个构造函数

func NewCheckUrlMiddleware(Redis *redis.Redis) *CheckUrlMiddleware {return &CheckUrlMiddleware{Redis: Redis}
}

接收一个redis客户端实例,返回一个新的CheckUrlMiddleware实例

后构造处理函数,包含具体的逻辑

func (m *CheckUrlMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {// 中间件的逻辑}
}

符合gozero中间件的签名,接收一个handlerfunc,返回一个新的handlerfunc

之后,我们在配置svc context内容

  1. Redis *redis.Redis

  2. CheckUrl rest.Middleware


  1. CheckUrl: middleware.NewCheckUrlMiddleware(newRedis).Handle,

  2. Redis: newRedis,

之后在启动文件添加server.Use(ctx.CheckUrl)就可以了


总结

本文介绍了GoZero官方已经提供的中间件以及启用方式,同时介绍了实现自定义中间件的两种方案,本文的局限为没有讲述怎么设置哪些路由使用中间件,后续会再继续补充

额外的,如果是解决GoZero跨源访问问题,官方已经给出了方便的实现,不用自定义中间件,具体方式为在启动文件修改如下一行

server := rest.MustNewServer(c.RestConf, rest.WithCors())

这篇关于GoZero微服务个人探究之路(七)添加中间件、自定义中间件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/628822

相关文章

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

关于DNS域名解析服务

《关于DNS域名解析服务》:本文主要介绍关于DNS域名解析服务,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录DNS系统的作用及类型DNS使用的协议及端口号DNS系统的分布式数据结构DNS的分布式互联网解析库域名体系结构两种查询方式DNS服务器类型统计构建DNS域

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3