前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 语言 Web 编程系列(六)—— 基于 gorilla/mux 包实现路由匹配:路由中间件

Go 语言 Web 编程系列(六)—— 基于 gorilla/mux 包实现路由匹配:路由中间件

作者头像
学院君
发布2020-01-17 15:35:11
1.2K0
发布2020-01-17 15:35:11
举报
文章被收录于专栏:学院君的专栏学院君的专栏

和 Laravel 路由一样,Mux 也支持在路由中使用中间件,并且按照顺序匹配执行。如果你对中间件不太了解,可以先去看下我们在 Laravel 中间件文档中的简单介绍:https://xueyuanjun.com/post/19926。和 Laravel 一样,在 Go Web 编程中,中间件的典型使用场景包括认证、日志、请求头操作和 ResponseWriter “劫持”等。

一个典型的 Mux 路由中间件通常通过一个闭包来定义,我们可以在闭包函数中处理传入的请求和响应实例或增加额外业务逻辑,然后调用传入的处理器继续后续请求处理(可能是下一个中间件或者最终的路由处理器)。比如,我们可以这样定义一个日志中间件:

代码语言:javascript
复制
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        log.Println(r.RequestURI)
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}
代码语言:javascript
复制

这个实现和 Laravel 中间件非常相似,通过类比的方式很容易理解:

代码语言:javascript
复制
代码语言:javascript
复制
<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class RequestLog
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
{
        Log::info(request()->url());
        return $next($request);
    }
}

如果要将上述 Mux 日志中间件应用到所有路由,可以通过 Use 方法实现:

代码语言:javascript
复制
代码语言:javascript
复制
r := mux.NewRouter()
r.Use(loggingMiddleware)

还可以将其批量应用到子路由,以便限定其作用范围:

代码语言:javascript
复制
代码语言:javascript
复制
postRouter := r.PathPrefix("/posts").Subrouter()
postRouter.Use(loggingMiddleware)

当然,上述日志中间件的定义非常简单,没有涉及请求处理和异常中断,我们可以仿照 Laravel 中间件文档中的 CheckToken 示例实现 Mux 版本的令牌检查中间件:

代码语言:javascript
复制
代码语言:javascript
复制
func checkToken(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        token := r.FormValue("token")
        if token == "xueyuanjun.com" {
            log.Printf("Token check success: %s\n", r.RequestURI)
            // Call the next handler, which can be another middleware in the chain, or the final handler.
            next.ServeHTTP(w, r)
        } else {
            http.Error(w, "Forbidden", http.StatusForbidden)
        }
    })
}

我们将其应用到 postRouter 子路由:

代码语言:javascript
复制
postRouter := r.PathPrefix("/posts").Subrouter()
postRouter.Use(checkToken)

重新启动 Go HTTP 服务器,访问任意 posts 子路由,就会被拒绝访问:

只有传递了正确的 token 参数才可以正常访问:

如果我们将日志中间件应用到全局路由器的话,此时可以在日志输出中看到所有请求的日志信息:

关于 Mux 路由中间件我们就简单介绍到这里,下一篇教程,我们继续探索 Mux 路由的其它用法,比如处理静态文件和单页面应用。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客书房 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档