在Go中简单实现HTTP服务中间件
通常一个简单http服务框架,就是注册一堆路由,然后根据路由调用不同的逻辑去处理。
但实际上可能有一些统一的处理对几乎所有的路由都涉及到,比如日志,比如权限等等。
那么这个时候搞一个中间做预处理,是一个不错的想法。
定义一个中间件单元:
package main import (
"net/http"
) // AdaptorHandle middleware func type
type AdaptorHandle func(w http.ResponseWriter, r *http.Request) (next bool, err error) // MiddleWareAdaptor router middlewares mapped by url
type MiddleWareAdaptor struct {
URLs map[string][]AdaptorHandle
} // MakeMiddleWareAdaptor make a middleware adaptor
func MakeMiddleWareAdaptor() *MiddleWareAdaptor {
mwa := &MiddleWareAdaptor{
URLs: make(map[string][]AdaptorHandle),
} return mwa
} // Regist regist a adaptor
func (mw *MiddleWareAdaptor) Regist(url string, Adaptor ...AdaptorHandle) {
for _, adp := range Adaptor {
mw.URLs[url] = append(mw.URLs[url], adp)
// mw.URLs[url] = adp
}
} // Exec exec middleware adaptor funcs...
func (mw *MiddleWareAdaptor) Exec(url string, w http.ResponseWriter, r *http.Request) (bool, error) {
if adps, ok := mw.URLs[url]; ok {
for _, adp := range adps {
if next, err := adp(w, r); !next || (err != nil) {
return next, err
}
}
}
return true, nil
}
然后将路由处理函数用中间件入口包裹起来:
func middlewareHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// before call handler
start := time.Now()
do, _ := mwa.Exec(r.URL.Path, w, r) // exec middleware
// call next handler
if do {
log.Println("middleware done. next...")
next.ServeHTTP(w, r)
} else {
log.Println("middleware done.break...")
}
// after call handle
log.Printf("Comleted %s in %v", r.URL.Path, time.Since(start))
})
}
mux.Handle("/", middlewareHandler(&uPlusRouterHandler{}))
type uPlusRouterHandler struct {
}
func (rh *uPlusRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
...
}
最后注册你需要的中间件即可:
mwa = MakeMiddleWareAdaptor() // init middleware
mwa.Regist("/", testMWAfunc, testMWAfunc2) // regist middleware
...
func testMWAfunc(w http.ResponseWriter, r *http.Request) (bool, error) {
log.Println("我是第一个中间件...")
log.Printf("Started %s %s", r.Method, r.URL.Path)
return true, nil
} func testMWAfunc2(w http.ResponseWriter, r *http.Request) (bool, error) {
log.Println("我是第二个中间件...")
return false, nil // return false,break follow-up actions.
}
代码虽然简单,记录一个思路。
在Go中简单实现HTTP服务中间件的更多相关文章
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- JAVAEE——宜立方商城02:服务中间件dubbo、工程改造为基于soa架构、商品列表实现
1. 学习计划 第二天:商品列表功能实现 1.服务中间件dubbo 2.工程改造为基于soa架构 3.商品列表查询功能实现. 2. 将工程改造为SOA架构 2.1. 分析 由于宜立方商城是基于soa的 ...
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...
- 我们都可以把它放 Sidecar 容器中,这样微服务具备了 Super power,一种超能力
云原生时代,微服务如何演进? 原创 李响 阿里技术 2020-08-28 https://mp.weixin.qq.com/s/KQG2U8_aotDL4YFB8ee6Zw 一 微服务架构与云原 ...
- nodejs创建一个简单的web服务
这是一个突如其来的想法,毕竟做web服务的框架那么多,为什么要选择nodejs,因为玩前端时,偶尔想调用接口获取数据,而不想关注业务逻辑,只是想获取数据,使用java或者.net每次修改更新后还要打包 ...
- BI实施过程中的工具与服务
成功的BI项目,不仅仅是应用了BI工具软件,还要具备完善的BI服务体系,才能称之为真正成功的商业智能bi项目. 现在的BI(商业智能)比起几年前的ERP一样,成为CIO们关注的焦点.在ERP等基础信息 ...
- 在Android开发中调用Rest web服务(转)
首先从维基百科上拷贝一点Rest的基本概念给大家看看,然后我们再开始详解在Android中如何调用Rest服务.表象化状态转变(英文:Representational State Transfer,简 ...
- 3D语音天气球(源码分享)——在Unity中使用Android语音服务
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...
- 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介
构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...
随机推荐
- 单片机模块化程序: 单片机加入JSON是个不错的选择
这节需要知道的知识点 https://www.cnblogs.com/yangfengwu/p/11685325.html 下载JSON文件: 链接: https://sourcefo ...
- 2019 NOIP 夏令营(模拟赛1)
一来到夏令营,第一天上机就考试, 哎,简直不让人活了 这难道是给我们的见面礼??? A https://www.luogu.org/problemnew/show/P1197 #include< ...
- 洛谷2320 bzoj1192 鬼谷子的钱袋
题目链接 题意概述:把正整数n分为m个正整数,m个正整数中不允许出现复数个非1的正整数,保证所有小于n的正整数都可以用一部分正整数的和表示,并且使m尽量小. 这道题不知道为啥bzoj上没有要求输出方案 ...
- from表格
目录 from 功能: 表单元素 表单工作原理: input 属性说明: select标签 属性说明: label标签 属性说明: from 功能: 表单用于向服务器传输数据,从而实现用户与Web服务 ...
- 第09组 Alpha事后诸葛亮
组长博客链接 组长博客 参考邹欣老师的问题模板进行总结思考 设想和目标(2分) 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决的问题 我们软件初期旨在解决 ...
- 第08组 Alpha冲刺(6/6)
队名:955 组长博客:https://www.cnblogs.com/cclong/p/11913269.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...
- hosts 屏蔽广告 定位
hosts 屏蔽广告 定位 JS Miner 挖矿 百度全家桶的全天候定位记录 各类统计服务(仅屏蔽 JS.不屏蔽控制台) 常见下载劫持 360 和百度的部分软件下载 CNNIC 根证书劫持 http ...
- 性能测试-GC问题整理
年轻代与老年代的调优(笔记整理) 几个常见名词 年轻代(young 区)从年轻代空间(包括Eden和Survivor 区域)回收内存被称为 Minor GC空间太小可能导致对象直接进入 old区 .如 ...
- jmeter(五十一)_性能测试中的服务器资源监控与分析
概述 性能测试过程中,对服务器资源的监控是必不可少的.这里的资源又分了两块,windows和linux linux下监控资源 访问网址http://jmeter-plugins.org/downl ...
- EAccessViolation
Access Violation(非法访问),General Protection Fault(一般保护性错误)或者Invalid Page Fault(无效页面错误),虽然说法不一样,但本质上总是由 ...