golang极速HTTP路由及RESTful API构建插件库ozzo-routing的使用

Golang极速HTTP路由及RESTful API构建插件库ozzo-routing的使用

ozzo-routing是一个高性能的Go HTTP路由库,专为Web应用开发设计,特别适合构建RESTful API。以下是它的主要功能和使用方法。

主要特性

  • 类似Express框架的中间件管道架构
  • 极速请求路由,零动态内存分配
  • 通过路由分组实现模块化代码组织
  • 灵活的URL路径匹配,支持URL参数和正则表达式
  • 兼容http.Handlerhttp.HandlerFunc
  • 提供构建RESTful API所需的现成处理器
  • 支持优雅关机

安装

使用Go模块安装ozzo-routing:

go get github.com/go-ozzo/ozzo-routing/v2

快速入门

创建一个简单的REST API服务器:

package main

import (
	"log"
	"net/http"
	"github.com/go-ozzo/ozzo-routing/v2"
	"github.com/go-ozzo/ozzo-routing/v2/access"
	"github.com/go-ozzo/ozzo-routing/v2/slash"
	"github.com/go-ozzo/ozzo-routing/v2/content"
	"github.com/go-ozzo/ozzo-routing/v2/fault"
	"github.com/go-ozzo/ozzo-routing/v2/file"
)

func main() {
	router := routing.New()

	// 全局中间件
	router.Use(
		access.Logger(log.Printf),           // 请求日志
		slash.Remover(http.StatusMovedPermanently), // 移除末尾斜杠
		fault.Recovery(log.Printf),          // 错误恢复
	)

	// API路由组
	api := router.Group("/api")
	api.Use(
		content.TypeNegotiator(content.JSON, content.XML), // 内容协商
	)
	
	// 用户相关路由
	api.Get("/users", func(c *routing.Context) error {
		return c.Write("user list")
	})
	api.Post("/users", func(c *routing.Context) error {
		return c.Write("create a new user")
	})
	api.Put(`/users/<id:\d+>`, func(c *routing.Context) error {
		return c.Write("update user " + c.Param("id"))
	})

	// 静态文件服务
	router.Get("/", file.Content("ui/index.html"))
	router.Get("/*", file.Server(file.PathMap{
		"/": "/ui/",
	}))

	http.Handle("/", router)
	http.ListenAndServe(":8080", nil)
}

路由定义

ozzo-routing使用路由表匹配请求:

router := routing.New()
router.To("GET", "/users", m1, m2, h1)
router.To("POST", "/users", m1, m2, h2)

或使用快捷方法:

router.Get("/users", m1, m2, h1)
router.Post("/users", m1, m2, h2)

支持链式调用:

router.Get("/users", m1, m2, h1).Post(m1, m2, h2)

路由参数

路径中可以包含参数:

router.Get("/users/<username>", func(c *routing.Context) error {
    fmt.Fprintf(c.Response, "Name: %v", c.Param("username"))
    return nil
})

支持正则表达式参数:

router.Get("/users/accnt-<id:\d+>", h1)  // 只匹配数字ID

路由分组

路由分组共享前缀和中间件:

router := routing.New()
api := router.Group("/api")
api.Use(m1, m2)

users := api.Group("/users")
users.Use(m3)
users.Put("/<id>", h1)

请求数据处理

读取请求数据到结构体:

func foo(c *routing.Context) error {
    data := &struct{
        A string
        B bool
    }{}

    if err := c.Read(&data); err != nil {
        return err
    }
    // 处理data...
}

内置处理器

ozzo-routing提供多种内置处理器:

  • access.Logger - 请求日志记录
  • auth.Basic - HTTP基本认证
  • content.TypeNegotiator - 内容协商
  • cors.Handler - CORS支持
  • fault.Recovery - 错误恢复
  • file.Server - 静态文件服务

性能

ozzo-routing性能优异,与Gin和httprouter相当:

BenchmarkOzzo_GithubAll      50000     37989 ns/op     0 B/op    0 allocs/op
BenchmarkGin_GithubAll       50000     26717 ns/op     0 B/op    0 allocs/op
BenchmarkHttpRouter_GithubAll 50000    36052 ns/op 13792 B/op  167 allocs/op

总结

ozzo-routing是一个功能丰富、性能优异的Go HTTP路由库,特别适合构建RESTful API。它的中间件架构、路由分组和丰富的内置处理器可以显著提高开发效率。


更多关于golang极速HTTP路由及RESTful API构建插件库ozzo-routing的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang极速HTTP路由及RESTful API构建插件库ozzo-routing的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


ozzo-routing:Golang极速HTTP路由及RESTful API构建插件库

ozzo-routing是一个轻量级但功能强大的Go语言HTTP路由库,专为构建高性能RESTful API而设计。它提供了简洁的API、中间件支持和丰富的功能扩展。

主要特性

  1. 极高性能:基于高效路由算法,处理速度接近原生net/http
  2. RESTful支持:天然支持RESTful风格API设计
  3. 中间件链:灵活的中间件机制
  4. 错误处理:统一的错误处理机制
  5. 数据绑定:自动将请求数据绑定到结构体
  6. 数据验证:内置数据验证功能

安装

go get github.com/go-ozzo/ozzo-routing/v2

基础使用示例

package main

import (
	"net/http"
	
	"github.com/go-ozzo/ozzo-routing/v2"
	"github.com/go-ozzo/ozzo-routing/v2/content"
	"github.com/go-ozzo/ozzo-routing/v2/cors"
)

func main() {
	router := routing.New()
	
	// 使用JSON响应中间件
	router.Use(
		content.TypeNegotiator(content.JSON),
		cors.Handler(cors.Options{
			AllowOrigins: "*",
			AllowHeaders: "*",
			AllowMethods: "*",
		}),
	)
	
	// 定义路由组
	api := router.Group("/api")
	
	// GET /api/ping
	api.Get("/ping", func(c *routing.Context) error {
		return c.Write("pong")
	})
	
	// POST /api/echo
	api.Post("/echo", func(c *routing.Context) error {
		var data struct {
			Message string `json:"message"`
		}
		
		// 绑定JSON请求体
		if err := c.Read(&data); err != nil {
			return err
		}
		
		return c.Write(map[string]string{
			"received": data.Message,
		})
	})
	
	http.Handle("/", router)
	http.ListenAndServe(":8080", nil)
}

RESTful资源路由

// 用户资源控制器
type UserController struct{}

func (uc *UserController) Get(c *routing.Context) error {
	id := c.Param("id")
	// 这里应该是从数据库获取用户逻辑
	return c.Write(map[string]string{
		"id":   id,
		"name": "User " + id,
	})
}

func (uc *UserController) Post(c *routing.Context) error {
	var user struct {
		Name  string `json:"name"`
		Email string `json:"email"`
	}
	
	if err := c.Read(&user); err != nil {
		return err
	}
	
	// 这里应该是创建用户逻辑
	return c.Write(map[string]interface{}{
		"status": "created",
		"user":   user,
	})
}

func main() {
	router := routing.New()
	router.Use(content.TypeNegotiator(content.JSON))
	
	// RESTful路由
	router.To("GET,POST", "/users", new(UserController))
	router.To("GET,PUT,DELETE", "/users/<id>", new(UserController))
	
	http.ListenAndServe(":8080", router)
}

中间件使用

ozzo-routing的中间件机制非常灵活:

func AuthMiddleware(c *routing.Context) error {
	token := c.Request.Header.Get("Authorization")
	if token != "valid-token" {
		return c.WriteWithStatus(map[string]string{
			"error": "Unauthorized",
		}, http.StatusUnauthorized)
	}
	return nil
}

func LoggingMiddleware(c *routing.Context) error {
	// 请求前处理
	start := time.Now()
	
	// 继续处理请求
	err := c.Next()
	
	// 请求后处理
	log.Printf(
		"[%s] %s %s %s %v",
		c.Request.Method,
		c.Request.URL.Path,
		c.Request.RemoteAddr,
		time.Since(start),
		err,
	)
	
	return err
}

func main() {
	router := routing.New()
	
	// 全局中间件
	router.Use(
		LoggingMiddleware,
		content.TypeNegotiator(content.JSON),
	)
	
	// 需要认证的路由组
	authGroup := router.Group("")
	authGroup.Use(AuthMiddleware)
	
	authGroup.Get("/secure", func(c *routing.Context) error {
		return c.Write("Secure content")
	})
	
	http.ListenAndServe(":8080", router)
}

错误处理

ozzo-routing提供了统一的错误处理机制:

type ErrorResponse struct {
	Error  string `json:"error"`
	Status int    `json:"status"`
}

func ErrorHandler(status int, err error) routing.Handler {
	return func(c *routing.Context) error {
		return c.WriteWithStatus(ErrorResponse{
			Error:  err.Error(),
			Status: status,
		}, status)
	}
}

func main() {
	router := routing.New()
	router.Use(
		content.TypeNegotiator(content.JSON),
	)
	
	// 注册错误处理器
	router.Get("/error", func(c *routing.Context) error {
		// 模拟错误
		return routing.NewHTTPError(http.StatusBadRequest, "Invalid request")
	})
	
	// 自定义错误处理中间件
	router.Use(func(c *routing.Context) error {
		err := c.Next()
		
		if err == nil {
			return nil
		}
		
		if httpErr, ok := err.(routing.HTTPError); ok {
			return ErrorHandler(httpErr.StatusCode(), httpErr)(c)
		}
		
		return ErrorHandler(http.StatusInternalServerError, err)(c)
	})
	
	http.ListenAndServe(":8080", router)
}

数据验证

ozzo-routing内置了数据验证功能:

type User struct {
	Name     string `json:"name"`
	Email    string `json:"email"`
	Password string `json:"password"`
}

func (u User) Validate() error {
	return validation.ValidateStruct(&u,
		validation.Field(&u.Name, validation.Required, validation.Length(2, 50)),
		validation.Field(&u.Email, validation.Required, validation.Length(5, 100)),
		validation.Field(&u.Password, validation.Required, validation.Length(6, 50)),
	)
}

func main() {
	router := routing.New()
	router.Use(content.TypeNegotiator(content.JSON))
	
	router.Post("/users", func(c *routing.Context) error {
		var user User
		if err := c.Read(&user); err != nil {
			return err
		}
		
		// 验证数据
		if err := user.Validate(); err != nil {
			return err
		}
		
		// 处理有效数据...
		return c.Write(map[string]string{"status": "created"})
	})
	
	http.ListenAndServe(":8080", router)
}

性能优化建议

  1. 尽量减少中间件数量,只添加必要的中间件
  2. 对于高并发场景,考虑使用路由缓存
  3. 避免在中间件中进行耗时的同步操作
  4. 使用路由组来组织相关路由,提高匹配效率

ozzo-routing是一个非常适合构建高性能RESTful API的轻量级框架,它的设计简洁但功能强大,是传统重量级框架如Gin或Echo之外的优秀选择。

回到顶部