自定义http服务+中间件案例
2023-02-25 18:22:00 时间
2023年即将到来,祝2023年更好
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
)
// MiddlewareFunc 中间件的函数
type MiddlewareFunc func(ctx context.Context, req interface{}) (resp interface{}, err error)
// Middleware 构建中间件函数使用
type Middleware func(MiddlewareFunc) MiddlewareFunc
// LogFile LogFile
type LogFile struct {
logName string
}
// buildMiddleWare 构建一个中间件函数
func buildMiddleWare(handle MiddlewareFunc) MiddlewareFunc {
var chain []Middleware
var LogFiler LogFile
chain = append(chain, frontHook)
chain = append(chain, newPrintLog(LogFiler))
middle := buildChain(chain)
return middle(handle)
}
// buildChain 构建链
/**
把中间件的数组构建成个链
最先执行的在最外层
next执行下一个 执行顺序和数组顺序相反
*/
func buildChain(chain []Middleware) Middleware {
return func(next MiddlewareFunc) MiddlewareFunc {
for i := len(chain) - 1; i >= 0; i-- {
next = chain[i](next)
}
return next
}
}
// frontHook 执行前置中间件
func frontHook(next MiddlewareFunc) MiddlewareFunc {
return func(ctx context.Context, req interface{}) (resp interface{}, err error) {
fmt.Println("执行前置中间件")
startTime := time.Now().UnixNano() / 1e6
resp, err = next(ctx, req) // 执行下一个
if err != nil {
log.Fatal(err)
return
}
endTime := time.Now().UnixNano() / 1e6
fmt.Println("函数执行时间为:", endTime-startTime)
return
}
}
// newPrintLog 打印日志中间件
func newPrintLog(LogFiler LogFile) Middleware {
return func(next MiddlewareFunc) MiddlewareFunc {
return func(ctx context.Context, req interface{}) (resp interface{}, err error) {
fmt.Println("打印日志中间件")
fmt.Println(LogFiler.logName, req)
resp, err = next(ctx, req)
return
}
}
}
// customHandler 自定义函数
func customHandler(ctx context.Context, req interface{}) (resp interface{}, err error) {
resp = req
fmt.Println("customHandle")
time.Sleep(time.Second)
return
}
// router router
func router(writer http.ResponseWriter, request *http.Request) {
MiddlewareFunction := buildMiddleWare(customHandler)
_, err := MiddlewareFunction(context.Background(), request)
if err != nil {
log.Fatal(err)
return
}
_, _ = writer.Write([]byte("<h1 style='color:red;'>2023水一贴</h1>"))
}
func main() {
//注册路由
http.HandleFunc("/", router)
//建立监听
err := http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", 8089), nil)
if err != nil {
log.Fatal(err)
return
}
}
相关文章
- 用 TS 类型系统实现大数加法
- 用React和Typescript编写纯净代码的十一种必备模式
- 系统学习 TypeScript之开发流程和语法规则
- 雪花算法:分布式唯一ID生成利器
- 系统学习 TypeScript 之一认识 TypeScript
- 一分钟了解 RSA 算法到底是个什么鬼?
- 前后端分离项目,如何解决跨域问题?
- 如何使用 Travis CI 构建 CI/CD 管道
- 大厂偏爱的 Agent 技术究竟是个啥
- 三分钟带你用 Go 语言实现枚举
- Git 实践,什么才是优秀的工作流?
- 探讨两种 Option 编程模式的实现
- 一个活跃在众多 Go 项目中的编程模式
- 理解了面向对象,我突破了地元境,代码写的真棒!
- 玩转Nacos参数配置!多图勿点
- Golang 语言 gRPC 服务怎么同时支持 gRPC 和 HTTP 客户端调用?
- 选择嵌入式编程语言的五个技巧
- PC有电源适配器,设计模式也有适配器模式,你知道吗
- 聊聊TopK 算法的多种实现
- 全面的动态规划入门指南帮你决胜技术面试