Skip to content
基于httprouter的路由模块
Go
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples 更新部分功能 Nov 23, 2018
.gitignore update Oct 22, 2018
LICENSE Initial commit Oct 20, 2018
README.md update readme Oct 28, 2018
context.go 添加部分响应方法 Nov 24, 2018
controller.go 更新部分功能 Nov 23, 2018
glide.lock update Oct 21, 2018
glide.yaml update Oct 21, 2018
go.mod 更新部分功能 Nov 23, 2018
go.sum 更新部分功能 Nov 23, 2018
params_go17.go update Oct 26, 2018
params_legacy.go update Oct 22, 2018
path.go update Oct 22, 2018
path_test.go update Oct 22, 2018
pipeline.go update Oct 27, 2018
route.go 更新部分功能 Nov 23, 2018
router.go 更新部分功能 Nov 23, 2018
router_test.go update Oct 22, 2018
tree.go tree Oct 27, 2018
tree_test.go update Oct 22, 2018

README.md

bingo-router

基于httprouter的路由模块

简介

这个包是为了自己的go web项目 Bingo 所开发的模块之一,负责核心路由功能,这里将其抽出来作为单独包, 可以轻松的在其他项目中使用,而无需依赖 Bingo 框架

特性:

  • 路由快速查找

  • 动态路由传参

  • 子路由支持(路由组)

  • 中间件支持

bingo-router 基于 httprouter , 性能强劲, httprouter 拥有的特性,bingo-router也有,并且参考 LaravelPipeline 功能,为 bingo-router 添加中间件支持,可以快速实现拦截器等常见功能

后续准备加入的功能

  • 会话管理

  • 路由跳转

  • 服务的平滑重启和关闭

  • 工具方法补充(e.g.封装json返回等方法)

  • 测试代码补充

安装

go get -u github.com/silsuer/bingo-router

bingo-router 使用 glide 管理依赖,如果遇到无法 go install 问题,请先安装 glide 后,去 $PATH/src/github.com/silsuer/bingo-router 目录下执行 glide install 命令安装依赖

使用

bingo-router 已内置在 [Bingo](https://github.com/silsuer/bingo) 框架中,开箱即用,对于第三方项目:

  1. 初始化路由器对象 router:
  	// 创建一个路由器
  	router := bingo_router.New()

路由器 Router 上挂载路由 Route,一个服务只能存在一个 Router,可存在多个Route,不要弄混

  1. 创建路由
  route := bingo_router.NewRoute().Get("/").Target(func(c *bingo_router.Context) {
  		fmt.Fprint(c.Writer,"hello! bingo-router!")
  	})

目前上下文对象context只是对 httprouter 中对象的一个简单封装,用法与 httprouter 完全一致:

  type Context struct {
  	Writer  http.ResponseWriter // 响应
  	Request *http.Request       // 请求
  	Params  Params              //参数
  }

NewRoute 方法将会返回一个路由指针,可以调用:

  • Get() 方法,设定为Get方法

  • Post() 方法,设定为Get方法

  • Patch() 方法,设定为Get方法

  • Put() 方法,设定为Get方法

  • Delete() 方法,设定为Get方法

  • Handle() 方法,设定为Get方法

  • Target() 方法,指定该路由所对应的方法

  • Middleware() 方法,设定一个将在其中设置的中间件

  • MiddlewareGroup() 方法,批量设置中间件

  • Prefix() 方法,设置路由前缀,该前缀将对该路由的所有子路由有效,对当前路由无效

  • Mount() 方法,设置子路由

  1. 将路由挂载到路由器中
  router.Mount(route)

路由器 Router

  1. 开启服务器
  http.ListenAndServe(":8080", r)
  1. 在浏览器中访问 http://localhost:8080, 可以看到输出 hello, bingo-router!

进阶

1. 使用中间件

使用 NewRoute() 方法之后将会获得一个 Route 对象指针,采用责任链模式,随意进行链式操作:

  r2 := bingo_router.NewRoute().Get("/test").Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
  	fmt.Fprint(c.Writer,"middleware")
  	next(c)
  }).Target(func(c *bingo_router.Context) {
  	fmt.Fprintln(c.Writer,"target")
  })

中间件是一种 MiddlewareHandle 类型的方法 func(c *Context, next func(c *Context))

Middleware 方法传入一个回调函数,该函数接受两个参数,第一个参数context 是上下文,是封装的http.ResponseWriter,*http.Requesthttprouter.Params

第二个参数是 next 方法,用来指定何时跳入下一个中间件,主要是用来实现前置中间件和后置中间件功能,当执行 next 方法后,将会跳入下一个中间件,直到所有中间件运行完毕后,才会继续执行下面的代码

例如,上面的r2的效果是输出:

  middleware
  target

如果将中间件中的next() 方法向上提一行的话:

    r2 := bingo_router.NewRoute().Get("/test").Middleware(func(c *bingo_router.Context, next func(c *bingo_router.Context)) {
          next(c)
          fmt.Fprint(c.Writer,"middleware")
      }).Target(func(c *bingo_router.Context) {
          fmt.Fprintln(c.Writer,"target")
      })

这样将会输出:

   target
   middleware

这样就可以实现后置中间件的效果了,可以做一些访问完控制器方法之后的后续工作

当然,如果不在中间件中调用 next() 方法,请求就将在这个中间件中终止。

2. 使用中间件组

Route 对象的 MiddlewareGroup() 方法可以实现批量注册中间件的功能,传入一个 MiddlwareHandle 的数组即可,不再赘述

3. 使用子路由和路由前缀

Laravel 中,我们经常会用到路由组的概念,可以方便的进行整体控制,在 bingo-router 中,我也实现了这样的功能,但是bingo-router中没有路由组的概念,可以使用子路由实现类似效果,

调用 Route 对象的 Mount 方法添加子路由:

  bingo_router.NewRoute().Prefix("/api").Middleware(MiddlewareFunction).Mount(func(b *bingo_router.Builder) {
  		b.NewRoute().Get("/mount").Target(func(c *bingo_router.Context) {
  			fmt.Fprint(c.Writer, "hello mount")
  		})

  		b.NewRoute().Get("/mount2").Target(func(c *bingo_router.Context) {
              			fmt.Fprint(c.Writer, "hello mount2")
          })
  	})

Prefix 方法,传入一个字符串,这个字符串将作用在所有子路由路径前,例如上面的代码,我们最终的访问路径就是 /api/mount/api/mount2

Mount 方法传入一个 Builder 指针,我们可以调用 Builder对象的 NewRoute() 方法为当前路由添加子路由,例如上面的代码,我们在访问 /api/mount/api/mount2时都会经过我们指定的MiddlewareFunction 中间件

这个包还没有完全开发完成,后续会继续补充,也会在这两天内内置到 Bingo 框架中

请大家多多关注主框架 Bingo , 欢迎 STAR 、 PR

You can’t perform that action at this time.