zoukankan      html  css  js  c++  java
  • 在Go中简单实现HTTP服务中间件

    通常一个简单http服务框架,就是注册一堆路由,然后根据路由调用不同的逻辑去处理。

    但实际上可能有一些统一的处理对几乎所有的路由都涉及到,比如日志,比如权限等等。

    那么这个时候搞一个中间做预处理,是一个不错的想法。

    定义一个中间件单元:

     1 package main
     2 
     3 import (
     4     "net/http"
     5 )
     6 
     7 // AdaptorHandle middleware func type
     8 type AdaptorHandle func(w http.ResponseWriter, r *http.Request) (next bool, err error)
     9 
    10 // MiddleWareAdaptor router middlewares mapped by url
    11 type MiddleWareAdaptor struct {
    12     URLs map[string][]AdaptorHandle
    13 }
    14 
    15 // MakeMiddleWareAdaptor make a middleware adaptor
    16 func MakeMiddleWareAdaptor() *MiddleWareAdaptor {
    17     mwa := &MiddleWareAdaptor{
    18         URLs: make(map[string][]AdaptorHandle),
    19     }
    20 
    21     return mwa
    22 }
    23 
    24 // Regist regist a adaptor
    25 func (mw *MiddleWareAdaptor) Regist(url string, Adaptor ...AdaptorHandle) {
    26     for _, adp := range Adaptor {
    27         mw.URLs[url] = append(mw.URLs[url], adp)
    28         // mw.URLs[url] = adp
    29     }
    30 }
    31 
    32 // Exec exec middleware adaptor funcs...
    33 func (mw *MiddleWareAdaptor) Exec(url string, w http.ResponseWriter, r *http.Request) (bool, error) {
    34     if adps, ok := mw.URLs[url]; ok {
    35         for _, adp := range adps {
    36             if next, err := adp(w, r); !next || (err != nil) {
    37                 return next, err
    38             }
    39         }
    40     }
    41     return true, nil
    42 }

    然后将路由处理函数用中间件入口包裹起来:

     1 func middlewareHandler(next http.Handler) http.Handler {
     2     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
     3         // before call handler
     4         start := time.Now()
     5         do, _ := mwa.Exec(r.URL.Path, w, r) // exec middleware
     6         // call next handler
     7         if do {
     8             log.Println("middleware done. next...")
     9             next.ServeHTTP(w, r)
    10         } else {
    11             log.Println("middleware done.break...")
    12         }
    13         // after call handle
    14         log.Printf("Comleted %s in %v", r.URL.Path, time.Since(start))
    15     })
    16 }
    17 
    18 mux.Handle("/", middlewareHandler(&uPlusRouterHandler{}))
    19 
    20 type uPlusRouterHandler struct {
    21 }
    22 
    23 func (rh *uPlusRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    24 ...
    25 }
     

    最后注册你需要的中间件即可:

    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.
    }

    代码虽然简单,记录一个思路。

  • 相关阅读:
    LASSO回归原理和Python代码 | 线性回归 | 交叉验证
    初探投行 | 金融
    癌症疫苗 | Cancer Vaccines
    文献复现 | Machine Learning on Human Muscle Transcriptomic Data for Biomarker Discovery and TissueSpecific Drug Target Identification
    癌症研究必备基础知识 | 生信
    初探RNA | RNA分类 | miRNA | lncRNA
    PubMed文献数据挖掘
    罕见病 | 国内 | 国外 | 市场状态
    医保目录谈判 | 国家带量采购 | DRG/DIP支付方式改革 | 腾笼换鸟
    TCGA数据挖掘基本教程
  • 原文地址:https://www.cnblogs.com/codingnote/p/11265527.html
Copyright © 2011-2022 走看看