0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Go项目中引入中间件的目的和效果如何

阿铭linux 来源:思否开发者社区 作者:guyan0319 2021-08-14 14:24 次阅读

中间件是什么?Go 项目中引入中间件的目的和效果如何?本文详细介绍了Golang 中间件。

中间件是一种计算机 软件,可为 操作系统 提供的 软件应用程序 提供服务,以便于各个软件之间的沟通,特别是系统软件和应用软件。广泛用于 web 应用和面向服务的体系结构等。

纵观 GO 语言,中间件应用比较普遍,主要应用:

记录对服务器发送的请求(request)

处理服务器响应(response )

请求和处理之间做一个权限认证工作

远程调用

安全

等等

中间件处理程序是简单的http.Handler,它包装另一个http.Handler做请求的一些预处理和/或后处理。它被称为“中间件”,因为它位于 Go Web 服务器和实际处理程序之间的中间位置。

下面是一些中间件例子

记录日志中间件

package main

import (

“fmt”

“log”

“net/http”

func logging(f http.HandlerFunc) http.HandlerFunc {

return func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

f(w, r)

}

}

func foo(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “foo”)

}

func bar(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “bar”)

}

func main() {

http.HandleFunc(“/foo”, logging(foo))

http.HandleFunc(“/bar”, logging(bar))

http.ListenAndServe(“:8080”, nil)

}

访问 http://localhost:8080/foo

返回结果

foo

将上面示例修改下,也可以实现相同的功能。

package main

import (

“fmt”

“log”

“net/http”

func foo(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “foo”)

}

func bar(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “bar”)

}

func loggingMiddleware(next http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

next.ServeHTTP(w, r)

})

}

func main() {

http.Handle(“/foo”, loggingMiddleware(http.HandlerFunc(foo)))

http.Handle(“/bar”, loggingMiddleware(http.HandlerFunc(bar)))

http.ListenAndServe(“:8080”, nil)

}

访问 http://localhost:8080/foo

返回结果

foo

多中间件例子

package main

import (

“fmt”

“log”

“net/http”

time”

type Middleware func(http.HandlerFunc) http.HandlerFunc// Logging logs all requests with its path and the time it took to processfunc Logging() Middleware {

// Create a new Middleware

return func(f http.HandlerFunc) http.HandlerFunc {

// Define the http.HandlerFunc

return func(w http.ResponseWriter, r *http.Request) {

// Do middleware things

start := time.Now()

defer func() { log.Println(r.URL.Path, time.Since(start)) }()

// Call the next middleware/handler in chain

f(w, r)

}

}

}

// Method ensures that url can only be requested with a specific method, else returns a 400 Bad Requestfunc Method(m string) Middleware {

// Create a new Middleware

return func(f http.HandlerFunc) http.HandlerFunc {

// Define the http.HandlerFunc

return func(w http.ResponseWriter, r *http.Request) {

// Do middleware things

if r.Method != m {

http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)

return

}

// Call the next middleware/handler in chain

f(w, r)

}

}

}

// Chain applies middlewares to a http.HandlerFuncfunc Chain(f http.HandlerFunc, middlewares 。。.Middleware) http.HandlerFunc {

for _, m := range middlewares {

f = m(f)

}

return f

}

func Hello(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “hello world”)

}

func main() {

http.HandleFunc(“/”, Chain(Hello, Method(“GET”), Logging()))

http.ListenAndServe(“:8080”, nil)

}

中间件本身只是将其http.HandlerFunc作为其参数之一,包装它并返回一个新http.HandlerFunc的服务器来调用。在这里,我们定义了一种新类型Middleware,最终可以更容易地将多个中间件链接在一起。

当然我们也可以改成如下形式

package main

import (

“fmt”

“log”

“net/http”

“time”

type Middleware func(http.Handler) http.Handlerfunc Hello(w http.ResponseWriter, r *http.Request) {

fmt.Fprintln(w, “hello world”)

}

func Chain(f http.Handler, mmap 。。.Middleware) http.Handler {

for _, m := range mmap {

f = m(f)

}

return f

}

func Method(m string) Middleware {

return func(f http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

log.Println(r.URL.Path)

if r.Method != m {

http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)

return

}

f.ServeHTTP(w, r)

})

}

}

func Logging() Middleware {

return func(f http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

//log.Println(r.URL.Path)

// Do middleware things

start := time.Now()

defer func() { log.Println(r.URL.Path, time.Since(start)) }()

f.ServeHTTP(w, r)

})

}

}

func main() {

http.Handle(“/”, Chain(http.HandlerFunc(Hello), Method(“GET”), Logging()))

http.ListenAndServe(“:8080”, nil)

}

在 gin 框架下实现中间件

r := gin.Default() 创建带有默认中间件的路由,默认是包含 logger 和 recovery 中间件的

r :=gin.new() 创建带有没有中间件的路由

示例

package main

import (

“github.com/gin-gonic/gin”

“log”

“time”

func Logger() gin.HandlerFunc {

return func(c *gin.Context) {

t := time.Now()

// Set example variable

c.Set(“example”, “12345”)

// before request

c.Next()

// after request

latency := time.Since(t)

log.Print(latency) //时间 0s

// access the status we are sending

status := c.Writer.Status()

log.Println(status) //状态 200

}

}

func main() {

r := gin.New()

r.Use(Logger())

r.GET(“/test”, func(c *gin.Context) {

example := c.MustGet(“example”)。(string)

// it would print: “12345”

log.Println(example)

})

// Listen and serve on 0.0.0.0:8080

r.Run(“:8080”)

}

以上示例也可改为

package main

import (

“github.com/gin-gonic/gin”

“log”

“time”

func Logger() gin.HandlerFunc {

return func(c *gin.Context) {

t := time.Now()

// Set example variable

c.Set(“example”, “12345”)

// before request

c.Next()

// after request

latency := time.Since(t)

log.Print(latency) //时间 0s

// access the status we are sending

status := c.Writer.Status()

log.Println(status) //状态 200

}

}

func main() {

r := gin.New()

r.GET(“/test”, Logger(), func(c *gin.Context) {

example := c.MustGet(“example”)。(string)

// it would print: “12345”

log.Println(example)

})

// Listen and serve on 0.0.0.0:8080

r.Run(“:8080”)

}

即不用 r.use 添加中间件,直接将 Logger() 写到 r.GET 方法的参数里(“/test”之后)。

更多 gin 中间件示例可参考 https://github.com/gin-gonic/gin

转自:guyan0319

segmentfault.com/a/1190000018819804

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Web
    Web
    +关注

    关注

    2

    文章

    1235

    浏览量

    68446
  • 计算机
    +关注

    关注

    19

    文章

    6643

    浏览量

    84471
  • 服务器
    +关注

    关注

    12

    文章

    8103

    浏览量

    82485

原文标题:GO 中间件 Middleware

文章出处:【微信号:aming_linux,微信公众号:阿铭linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    求助,关于MDK5中间件network库静态ip手动配置问题

    最近在研究MDK5的自带的Middleware中间件库,其中用到NetWork库,ipv4及ipv6各项功能均已调通。发现MDK提供的network库并没有提供供用户手动修改设备Ip地址及mac地址
    发表于 04-22 08:09

    中间件厂商中创股份科创板上市

    山东中创软件商用中间件股份有限公司(以下简称“中创股份”)成功在上交所科创板上市,这标志着这家国内领先的基础软件中间件产品与服务提供商迈入了新的发展阶段。中创股份在国民经济重点行业领域,如金融、能源、交通等,拥有广泛的业务布局和深厚的技术积累。
    的头像 发表于 03-18 17:29 392次阅读

    中间件厂商中创股份成功上市

    近日,国内领先的基础软件中间件产品与服务提供商——山东中创软件商用中间件股份有限公司(以下简称“中创股份”)在上海证券交易所科创板上市,股票代码为“688695”。这一里程碑事件标志着中创股份在基础软件中间件领域的实力和影响力得
    的头像 发表于 03-14 15:25 369次阅读

    中创股份成功登陆科创板,深耕中间件行业

    3月13日,山东中创软件商用中间件股份有限公司(以下简称“中创股份”)在上海证券交易所科创板成功挂牌上市,标志着这家在中间件领域深耕二十余年的企业迎来了新的发展篇章。
    的头像 发表于 03-13 15:42 189次阅读

    基础软件中间件产品与服务提供商中创股份成功上市

    山东中创软件商用中间件股份有限公司(股票简称:中创股份,股票代码:688695)今日在上海证券交易所科创板成功上市,开启了公司发展的新篇章。作为中间件技术标准的主要推动者和制定者,中创股份在中间件
    的头像 发表于 03-13 14:21 199次阅读

    中创股份登陆科创板,国产中间件领域显身手

    近日,中间件产品与服务提供商中创股份(688695.SH)成功登陆上海证券交易所科创板,这一重要事件标志着中创股份在国产中间件需求增长的背景下,正迎来广阔的发展空间。
    的头像 发表于 03-13 14:09 220次阅读

    国产中间件提供商中创股份上市

    近日,国内中间件领域的领军企业——山东中创软件商用中间件股份有限公司(简称“中创股份”)在科创板成功上市,这一重要事件标志着中创股份在中间件行业深耕多年后,迎来了崭新的发展阶段。
    的头像 发表于 03-13 13:49 173次阅读

    Ai-WB2-12F使用安信可中间件接入爱星云,远程点个灯(2)

    上次已经给大家讲了如何搭建中间件SDK(Ai-WB2-12F使用安信可中间件接入爱星云,远程点个灯——第一篇)。经过上次的帖子,小伙伴们想必已经完成一个新项目的添加,并使用WB2编译成功,今天
    的头像 发表于 01-08 17:18 214次阅读
    Ai-WB2-12F使用安信可<b class='flag-5'>中间件</b>接入爱星云,远程点个灯(2)

    EDMS中间件集成的未来趋势和探讨

    ETAS Deterministic Middleware Solution (EDMS,前身为AOS)确定性中间件解决方案,是一个中间件框架,旨在面向汽车领域内应用程序的独特挑战和需求,尤其是
    的头像 发表于 09-28 10:03 1466次阅读
    EDMS<b class='flag-5'>中间件</b>集成的未来趋势和探讨

    在FRDM-K64F开发板上开发中间件应用程序

    本教程将指导您在FRDM-K64F开发板上开发中间件应用程序。 该应用程序从MEMS传感器(加速计和磁力计)读取数据,并使用CGI和JavaScript将其显示在网站上。 Web服务器
    发表于 09-04 08:02

    在MDK版本5中使用CMSIS组件创建中间件应用程序

    本研讨会介绍如何使用CMSIS和中间件组件为复杂的微控制器应用程序创建软件框架。 在本研讨会期间,将创建一个实现以下功能的演示应用程序: 从U盘读取“Test.txt”文件的内容。 在图形显示器上显示此内容。 在触摸屏上提供了更新按钮
    发表于 09-04 07:43

    i.MXRT1024 MCU是否有用于NXP WiFi的驱动程序和中间件

    i.MXRT1024 MCU 是否有用于 NXP WiFi 的驱动程序和中间件? MCUXpressoSDK 包含对多个基于 NXP WiFi 的模块以及许多 i.MXRT 处理器和 EVK
    发表于 06-09 07:37

    什么是DDS(数据分发服务)?#软件中间件

    中间件DDS
    北汇信息POLELINK
    发布于 :2023年06月05日 14:50:13

    自动驾驶通信中间件

    中间件”是一个比较抽象和宽泛的概念,它并不特指一种具体的技术,其概念起源于复杂分布式软件系统的开发,其目的是实 现软件组件之间进行数据交换,使软件组件之间实现解耦。这种数据交换通常是通过网络进行
    发表于 06-01 11:32 0次下载
    自动驾驶通信<b class='flag-5'>中间件</b>

    如何将以太网引脚分配反映到lwip中间件

    不知道这是如何绑定到网络接口初始化的。我想这一定与 lwip 中间件中的某些代码有关,但我到处搜索都没有成功。 任何人都知道如何反映自定义引脚分配?
    发表于 05-12 06:20