golang可组合中间件与处理器开发框架插件Siesta的使用

Golang可组合中间件与处理器开发框架插件Siesta的使用

Siesta是一个用于在Go中编写可组合HTTP处理程序的框架。它支持类型化的URL参数、中间件链和上下文传递。

快速入门

Siesta提供了一个Service类型,它是在基础URI上的一组中间件链和处理程序。中间件函数和处理函数之间没有区别,它们都被视为处理程序,并且可以访问相同的参数。

基本示例

以下是一个完整的示例demo,演示了如何使用Siesta的Service、路由、中间件和Context

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/VividCortex/siesta"
)

func main() {
	// 创建一个根路径为"/"的新Service
	service := siesta.NewService("/")

	// Route接受普通的http.Handlers
	// 参数分别是方法、路径、描述和处理程序
	service.Route("GET", "/", "发送'Hello, world!'",
		func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, world!")
	})

	// 创建一个简单的"中间件"
	// 这个处理程序将接受一个Context参数并将当前时间添加到其中
	timestamper := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set("start", time.Now())
	}

	// 这是实际将数据发送回客户端的处理程序
	// 它也接受Context参数,因此可以从上一个处理程序获取时间戳
	timeHandler := func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		start := c.Get("start").(time.Time)
		delta := time.Now().Sub(start)
		fmt.Fprintf(w, "耗时 %v.\n", delta)
	}

	// 我们可以将这些处理程序组合在一起
	timeHandlers := siesta.Compose(timestamper, timeHandler)

	// 最后,我们将使用组合创建的新处理程序添加到新路由
	service.Route("GET", "/time", "发送发送消息所需的时间", timeHandlers)

	// service是一个http.Handler,所以我们可以直接将它传递给ListenAndServe
	log.Fatal(http.ListenAndServe(":8080", service))
}

示例说明

  1. 首先创建一个根路径为"/"的Service实例
  2. 添加一个简单的GET路由,返回"Hello, world!"
  3. 创建一个中间件函数timestamper,它在Context中设置当前时间
  4. 创建一个处理函数timeHandler,它从Context获取时间并计算耗时
  5. 使用siesta.Compose将中间件和处理函数组合起来
  6. 将组合后的处理程序添加到新的路由"/time"
  7. 启动服务器监听8080端口

功能特点

  • 可组合的中间件:使用siesta.Compose可以轻松组合多个处理函数
  • 上下文传递:通过siesta.Context在不同处理函数之间共享数据
  • 简单路由:支持标准的HTTP方法和路径定义
  • 兼容性:Service实现了http.Handler接口,可以直接用于标准HTTP服务器

Siesta还提供了类似flag包的工具来管理URL参数,可以参考params示例了解详情。


更多关于golang可组合中间件与处理器开发框架插件Siesta的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang可组合中间件与处理器开发框架插件Siesta的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Siesta: Golang 可组合中间件与处理器开发框架

Siesta 是一个轻量级的 Go 语言 Web 框架,专注于中间件的可组合性和处理器的灵活性。它提供了一种简洁的方式来构建 Web 服务和 API。

核心概念

Siesta 的核心思想是将 HTTP 处理分解为可组合的中间件和处理器:

  1. 中间件(Middleware): 在请求处理前后执行逻辑
  2. 处理器(Handler): 实际处理请求并生成响应

安装

go get github.com/VividCortex/siesta

基本使用示例

package main

import (
	"fmt"
	"net/http"
	
	"github.com/VividCortex/siesta"
)

func main() {
	// 创建新的 Siesta 服务
	service := siesta.NewService("/api")
	
	// 添加中间件
	service.Use(loggingMiddleware)
	
	// 添加路由
	service.Route("GET", "/hello", "Says hello", helloHandler)
	
	// 启动服务
	http.ListenAndServe(":8080", service)
}

func loggingMiddleware(c siesta.Context, w http.ResponseWriter, r *http.Request, quit func()) {
	fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
	// 调用 quit() 会跳过后续中间件和处理器
}

func helloHandler(c siesta.Context, w http.ResponseWriter, r *http.Request) {
	name := c.Get("name").(string) // 从上下文中获取值
	fmt.Fprintf(w, "Hello, %s!", name)
}

中间件组合

Siesta 的强大之处在于中间件的可组合性:

func main() {
	service := siesta.NewService("/api")
	
	// 全局中间件
	service.Use(loggingMiddleware)
	service.Use(authMiddleware)
	
	// 特定路由的中间件
	adminGroup := service.Group("/admin")
	adminGroup.Use(adminAuthMiddleware)
	
	// 路由定义
	adminGroup.Route("GET", "/users", "List users", listUsersHandler)
}

上下文传递

Siesta 使用 Context 对象在中间件和处理器之间传递数据:

func authMiddleware(c siesta.Context, w http.ResponseWriter, r *http.Request, quit func()) {
	token := r.Header.Get("Authorization")
	if token == "" {
		w.WriteHeader(http.StatusUnauthorized)
		quit() // 停止后续处理
		return
	}
	
	// 将用户信息存入上下文
	user, err := getUserFromToken(token)
	if err != nil {
		w.WriteHeader(http.StatusUnauthorized)
		quit()
		return
	}
	
	c.Set("user", user)
}

func profileHandler(c siesta.Context, w http.ResponseWriter, r *http.Request) {
	user := c.Get("user").(*User)
	json.NewEncoder(w).Encode(user)
}

参数绑定

Siesta 支持请求参数的自动绑定:

type UserInput struct {
	Name  string `json:"name" form:"name"`
	Email string `json:"email" form:"email"`
}

func createUserHandler(c siesta.Context, w http.ResponseWriter, r *http.Request) {
	var input UserInput
	if err := c.Bind(&input); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "Invalid input: %v", err)
		return
	}
	
	// 使用 input 创建用户
	// ...
}

错误处理

可以自定义错误处理中间件:

func errorMiddleware(c siesta.Context, w http.ResponseWriter, r *http.Request, quit func()) {
	defer func() {
		if err := recover(); err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "Error: %v", err)
			quit()
		}
	}()
}

func main() {
	service := siesta.NewService("/api")
	service.Use(errorMiddleware)
	// ...
}

插件机制

Siesta 支持通过中间件实现插件功能:

func metricsMiddleware(collector *MetricsCollector) siesta.Middleware {
	return func(c siesta.Context, w http.ResponseWriter, r *http.Request, quit func()) {
		start := time.Now()
		
		// 调用下一个中间件或处理器
		quit = func() {
			duration := time.Since(start)
			collector.Record(r.Method, r.URL.Path, duration)
			quit()
		}
	}
}

func main() {
	collector := NewMetricsCollector()
	service := siesta.NewService("/api")
	service.Use(metricsMiddleware(collector))
	// ...
}

与标准库集成

Siesta 兼容 http.Handler 接口,可以轻松与其他库集成:

func main() {
	service := siesta.NewService("/api")
	
	// 使用标准库中间件
	recovery := negroni.NewRecovery()
	service.Use(func(c siesta.Context, w http.ResponseWriter, r *http.Request, quit func()) {
		recovery.ServeHTTP(w, r, func(w http.ResponseWriter, r *http.Request) {
			quit = func() {} // 防止提前退出
			service.ServeHTTP(w, r)
		})
	})
	
	http.ListenAndServe(":8080", service)
}

总结

Siesta 提供了以下优势:

  1. 简洁的中间件组合:通过 Use() 方法轻松组合中间件
  2. 灵活的上下文管理:在请求处理链中传递数据
  3. 标准库兼容:无缝集成现有 Go HTTP 生态
  4. 轻量级:不引入过多抽象,保持 Go 的简洁性

对于需要灵活中间件组合的中小型项目,Siesta 是一个值得考虑的选择。

回到顶部