路由/路由组

路由的原理是通过客户端请求的路径和方法来执行对应的一个或多个处理器函数,形参如下:

httpdispatcher.Router.方法("路径", 处理器)

GET路由

  1. //获得一个调度器的实例化对象
  2. var dispatcher = httpdispatcher.New()
  3.  
  4. //注册一个/路径的GET路由
  5. dispatcher.Router.GET("/", func(ctx *httpdispatcher.Context) error {
  6. log.Println("/路径的处理器")
  7. return nil
  8. })

POST路由

每个路由规则可以传入无限个路由处理器,按照先传入先执行的顺序执行,以下演示创建一个POST路由,并传入3个处理器:

  1. //注册一个路径为/的POST路由
  2. dispatcher.Router.POST("/",
  3. func(ctx *httpdispatcher.Context) error {
  4. log.Println("/路径的处理器A")
  5. //执行Next(true)表示继续执行后面的处理器
  6. return ctx.Next(true)
  7. },
  8. func(ctx *httpdispatcher.Context) error {
  9. log.Println("/路径的处理器B")
  10. //此处没有执行Next(true),后面的处理器C将不会执行
  11. return nil
  12. },
  13. func(ctx *httpdispatcher.Context) error {
  14. log.Println("/路径的处理器C")
  15. return nil
  16. },
  17. )

以上路由规则在使有POST方法请求"/"路径时会按以下顺序执行路由处理器:

  • /路径的处理器A
  • /路径的处理器B
    注意,本路由的三个处理器只执行了A和B两个,因为B处理器没有执行ctx.Next(true)来告知路由器可以继续执行后面的处理器,可以通过这个特性来实现身份验证的拦截等功能。

PUT/PATH/HEAD/OPTIONS/DELETE路由

httpdispatcher.Router.PUT("路径", 处理器)

httpdispatcher.Router.PATH("路径", 处理器)

httpdispatcher.Router.HEAD("路径", 处理器)

httpdispatcher.Router.OPTIONS("路径", 处理器)

httpdispatcher.Router.DELETE("路径", 处理器)

静态路由

HTTP Dispatcher支持目录和文件两种静态路由,可将整个目录或者某些文件直接暴露给HTTP客户端,示例如下:

  1. /*
  2. 注册目录路由,使目录里的内容直接暴露给HTTP客户端
  3. 第一个入参数为虚拟路径
  4. 第二个入参为物理目录的路径
  5. 第三个入参决定是否启用目录下的文件列表,当值为false时,直接访问目录会触发404错误
  6. */
  7. dispatcher.Router.PATH("/static", "./static", false)
  8.  
  9. /*
  10. 注册文件路由,使文件直接暴露给HTTP客户端
  11. 第一个入参为文件的虚拟路径
  12. 第二个入参为文件的物理路径
  13. */
  14. dispatcher.Router.FILE("/favicon.ico", "./favicon.ico")

注意:静态路由不支持处理器。

路由组

HTTP Dispatcher基于julienschmidt/httprouter包扩展了路由组功能,路由组支持无限层级的嵌套,以下是两层路由组的示例:

  1. //获得一个调度器的实例化对象
  2. var dispatcher = httpdispatcher.New()
  3.  
  4. //注册一个空路径的入口路由组
  5. rootRouter := dispatcher.Router.GROUP("",
  6. //第一个要执行的处理器
  7. func(ctx *httpdispatcher.Context) error {
  8. log.Println("入口路由组处理器A")
  9. //执行下一个处理器
  10. return ctx.Next(true)
  11. },
  12. //第二个要执行的处理器
  13. func(ctx *httpdispatcher.Context) error {
  14. log.Println("入口路由组处理器B")
  15. //执行下一个处理器
  16. return ctx.Next(true)
  17. },
  18. )
  19. //基于入口路由对象再创建一个路径为/news的子路由组
  20. newsRouter := rootRouter.GROUP("/news",
  21. func(ctx *httpdispatcher.Context) error {
  22. log.Println("/news路由组的处理器A")
  23. //执行下一个处理器
  24. return ctx.Next(true)
  25. },
  26. func(ctx *httpdispatcher.Context) error {
  27. log.Println("/news路由组的处理器B")
  28. //执行下一个处理器
  29. return ctx.Next(true)
  30. },
  31. )
  32. //注册一个路径为/的首页GET路由
  33. newsRouter.GET("/list",
  34. //第一个要执行的处理器
  35. func(ctx *httpdispatcher.Context) error {
  36. log.Println("/news/list路径的处理器A")
  37. //执行下一个处理器
  38. return ctx.Next(true)
  39. },
  40. func(ctx *httpdispatcher.Context) error {
  41. log.Println("/news/list路径的处理器B")
  42. //本处理器是最后一个,所以不需要再执行ctx.Next(true)
  43. return nil
  44. },
  45. )

以上路由规则在请求"/news/list"路径时会按以下顺序执行路由处理器:

  • 入口路由组处理器A
  • 入口路由组处理器B
  • /news路由组的处理器A
  • /news路由组的处理器B
  • /news/list路径的处理器B