Beego 使用教程 3:Web 模块之路由

本文详细介绍了Go语言Beego框架的Web模块路由,包括控制器风格路由的自动和手动路由,函数式风格路由的基本和参数路由,查看已注册路由的方法,以及命名空间的使用,包括基本使用、多种形式多路由、命名空间嵌套和Filter应用。

beego 是一个用于Go编程语言的开源、高性能的 web 框架

beego 被用于在Go语言中企业应用程序的快速开发,包括RESTful API、web应用程序和后端服务。它的灵感来源于Tornado, Sinatra 和 Flask

beego 官网:http://beego.gocn.vip/

上面的 beego 官网如果访问不到,看这篇文章《beego 官网文档本地环境搭建》

注意:本文的 beego 文档使用的就是本地环境搭建的文档,因为官网文档已经不可用了

beego 官方 github 仓库:https://github.com/beego/beego

上一讲,讲了 beego 的配置模块、Admin管理后台和定时任务,需要的朋友可以查看《Beego 使用教程 2:配置模块、Admin管理后台和定时任务》

这一讲,主要讲解 beego 的 Web 模块中的路由部分

笔者使用上一讲的代码

目录

1、控制器风格路由

1.1、自动路由

1.2、手动路由

1.2.1、基本路由

1.2.2、参数路由

2、函数式风格路由

2.1、基本路由

2.2、参数路由

3、查看已注册路由

4、命名空间

4.1、基本使用

4.2、多种形式多路由

4.3、命名空间嵌套

4.4、命名空间 Filter


1、控制器风格路由

1.1、自动路由

在项目根目录下新建 controller 目录,在 controller 目录下新建 user.go

在 controller 目录下 user.go 中添加下面代码

自动路由,即不需要指定请求路径,beego 会默认把请求地址 /user/name 映射到对应的方法

/user 是 UserController /name 是Name 方法

package controller

import "github.com/beego/beego/v2/server/web"

type UserController struct {
	web.Controller
}

func (u *UserController) Name() {
	u.Ctx.WriteString("春已半,触目此情无限。十二阑干闲倚遍,愁来天不管")
}

main.go 中代码如下

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	web.AutoRouter(&controller.UserController{})

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	web.Run()
}

启动项目后,请求 http://localhost:9090/user/name

运行效果

添加请求前缀

在 main.go 中修改 web.AutoRouter(&controller.UserController{}) 为 web.AutoPrefix("api", &controller.UserController{})

web.AutoRouter(&controller.UserController{})

main.go

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	web.AutoPrefix("api", &controller.UserController{})

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	web.Run()
}

重新启动项目,浏览器访问:http://localhost:9090/api/user/name

1.2、手动路由

上面的路由注册方式是自动注册路由,下面介绍手动注册路由的方式

1.2.1、基本路由

在 main.go 中注释掉自动注册路由的代码,修改为下面手动注册的代码

web.CtrlGet("/name", (*controller.UserController).Name)

main.go

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	//web.AutoPrefix("api", &controller.UserController{})
	web.CtrlGet("/name", (*controller.UserController).Name)

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	web.Run()
}

重新启动项目,浏览器访问:http://localhost:9090/name

1.2.2、参数路由

参数路由是手动路由的一种形式

注册请求参数是请求路径的的路由,使用:,看下面代码

注册路由

web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)

多参数

web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)

获取路由参数

id := u.Ctx.Input.Param(":id")

修改  controller 目录下 user.go 为下面代码

package controller

import "github.com/beego/beego/v2/server/web"

type UserController struct {
	web.Controller
}

func (u *UserController) Name() {
	u.Ctx.WriteString("春已半,触目此情无限。十二阑干闲倚遍,愁来天不管")
}

func (u *UserController) GetUserById() {
	id := u.Ctx.Input.Param(":id")
	u.Ctx.WriteString("好是风和日暖,输与莺莺燕燕。满院落花帘不卷,断肠芳草远 " + id)
}

func (u *UserController) GetUserByIdAndNum() {
	id := u.Ctx.Input.Param(":id")
	num := u.Ctx.Input.Param(":num")
	u.Ctx.WriteString("好是风和日暖,输与莺莺燕燕。满院落花帘不卷,断肠芳草远 " + id + " : " + num)
}

修改 main.go 为下面代码

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	//web.AutoPrefix("api", &controller.UserController{})
	web.CtrlGet("/name", (*controller.UserController).Name)
	web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)
	web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	web.Run()
}

运行效果

浏览器分别请求:http://localhost:9090/get/88

和 http://localhost:9090/get/88/999

2、函数式风格路由

2.1、基本路由

在 controller 目录下新建 book.go, book.go 中添加下面代码

package controller

import (
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

// RegisterFunctionalRoutes 注册函数式路由
func RegisterFunctionalRoutes() {
	web.Get("/book", func(ctx *context.Context) {
		ctx.WriteString("逢春触处须萦恨,对景无时不断肠")
	})
}

在 main.go 中添加注册函数式路由的方法

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	//web.AutoPrefix("api", &controller.UserController{})
	web.CtrlGet("/name", (*controller.UserController).Name)
	web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)
	web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)

	//注册函数式路由
	controller.RegisterFunctionalRoutes()

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	web.Run()
}

运行效果

浏览器访问:http://localhost:9090/book

2.2、参数路由

使用方法和控制器路由的参数路由方式一样,看下面代码

package controller

import (
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

// RegisterFunctionalRoutes 注册函数式路由
func RegisterFunctionalRoutes() {
	web.Get("/book", func(ctx *context.Context) {
		ctx.WriteString("逢春触处须萦恨,对景无时不断肠")
	})

	web.Get("/book/:id", func(ctx *context.Context) {
		id := ctx.Input.Param(":id")
		ctx.WriteString("楼外垂杨千万缕。欲系青春,少住春还去 " + id)
	})

	web.Get("/book/:id/:name", func(ctx *context.Context) {
		id := ctx.Input.Param(":id")
		name := ctx.Input.Param(":name")
		ctx.WriteString("犹自风前飘柳絮。随春且看归何处 " + id + " : " + name)
	})
}

3、查看已注册路由

web.PrintTree() 方法会把所有注册的路由信息返回

web.PrintTree()

修改 main.go 为下面代码

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	//web.AutoPrefix("api", &controller.UserController{})
	web.CtrlGet("/name", (*controller.UserController).Name)
	web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)
	web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)

	//注册函数式路由
	controller.RegisterFunctionalRoutes()

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	//查看已注册路由
	tree := web.PrintTree()
	methods := tree["Data"].(web.M)
	for k, v := range methods {
		fmt.Printf("%s => %v\n", k, v)
	}

	web.Run()
}

运行效果

4、命名空间

4.1、基本使用

在 controller 目录下新建 app.go, app.go 中添加下面代码

package controller

import (
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

// RegisterNamespaceRoutes web命名空间
func RegisterNamespaceRoutes() {
	namespace := web.NewNamespace("/v", web.NSGet("/get", func(ctx *context.Context) {
		ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
	}))

	web.AddNamespace(namespace)
}

在 main.go 中添加命名空间代码调用

package main

import (
	"beego-demo/controller"
	"fmt"
	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/server/web"
)

func main() {
	//通过config获取自定义配置
	workername, _ := config.String("workername")
	fmt.Println(workername)

	//执行定时任务
	//go job.DemoTask()

	//注册自动路由
	//web.AutoPrefix("api", &controller.UserController{})
	web.CtrlGet("/name", (*controller.UserController).Name)
	web.CtrlGet("/get/:id", (*controller.UserController).GetUserById)
	web.CtrlGet("/get/:id/:num", (*controller.UserController).GetUserByIdAndNum)

	//注册函数式路由
	controller.RegisterFunctionalRoutes()
	//web命名空间
	controller.RegisterNamespaceRoutes()

	//开启 Admin 管理后台
	web.BConfig.Listen.EnableAdmin = true
	web.BConfig.Listen.AdminAddr = "localhost"
	web.BConfig.Listen.AdminPort = 8088

	//查看已注册路由
	tree := web.PrintTree()
	methods := tree["Data"].(web.M)
	for k, v := range methods {
		fmt.Printf("%s => %v\n", k, v)
	}

	web.Run()
}

重启项目后台请求:http://localhost:9090/v/get

运行效果

4.2、多种形式多路由

上面的基本使用是在命名空间中添加了1个函数式路由

下面介绍添加多个路由,有函数式路由,控制风格路由(自动和手动)

修改  app.go 为下面代码

package controller

import (
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

type AddrController struct {
	web.Controller
}

type HobbyController struct {
	web.Controller
}

func (ac *AddrController) Home() {
	ac.Ctx.WriteString("辽宁-沈阳")
}

func (hc *HobbyController) Content() {
	hc.Ctx.WriteString("唱歌-跳舞")
}

// RegisterNamespaceRoutes web命名空间
func RegisterNamespaceRoutes() {
	namespace := web.NewNamespace("/v", web.NSGet("/get", func(ctx *context.Context) {
		ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
	}))

	hc := &HobbyController{}
	ns := web.NewNamespace("/app",
		//函数式路由
		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
		}),
		//控制风格路由手动形式
		web.NSCtrlGet("/find", (*AddrController).Home),
		//控制风格路由自动形式
		web.NSAutoRouter(hc),
	)

	web.AddNamespace(namespace)
	web.AddNamespace(ns)
}

运行效果

4.3、命名空间嵌套

命名空间(namespace)嵌套命名空间,可以使用 web.NSNamespace方法来注入一个子namespace

修改  app.go 为下面代码

package controller

import (
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

type AddrController struct {
	web.Controller
}

type HobbyController struct {
	web.Controller
}

func (ac *AddrController) Home() {
	ac.Ctx.WriteString("辽宁-沈阳")
}

func (hc *HobbyController) Content() {
	hc.Ctx.WriteString("唱歌-跳舞")
}

// RegisterNamespaceRoutes web命名空间
func RegisterNamespaceRoutes() {
	namespace := web.NewNamespace("/v", web.NSGet("/get", func(ctx *context.Context) {
		ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
	}))

	hc := &HobbyController{}
	ns := web.NewNamespace("/app",
		//函数式路由
		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
		}),
		//控制风格路由手动形式
		web.NSCtrlGet("/find", (*AddrController).Home),
		//控制风格路由自动形式
		web.NSAutoRouter(hc),
	)

	nsn := web.NewNamespace("/n",
		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("独行独坐,独唱独酬还独卧。伫立伤神,无奈轻寒著摸人")
		}),
		//嵌套命名空间
		web.NSNamespace("/app",
			web.NSGet("/get", func(ctx *context.Context) {
				ctx.WriteString("此情谁见,泪洗残妆无一半。愁病相仍,剔尽寒灯梦不成")
			}),
			web.NSGet("/find", func(ctx *context.Context) {
				ctx.WriteString("夜久无眠秋气清,烛花频剪欲三更")
			}),
		),
	)

	web.AddNamespace(namespace)
	web.AddNamespace(ns)
	web.AddNamespace(nsn)
}

运行效果

4.4、命名空间 Filter

命名空间(namespace)同样支持 filter。该filter 只会作用于这个namespace之下注册的路由,而对别的路由没有影响

有两种方式添加Filter,一种是在 NewNamespace中,调用web.NSBefore 方法,也可以调用 ns.Filter()

修改  app.go 为下面代码

package controller

import (
	"fmt"
	"github.com/beego/beego/v2/server/web"
	"github.com/beego/beego/v2/server/web/context"
)

type AddrController struct {
	web.Controller
}

type HobbyController struct {
	web.Controller
}

func (ac *AddrController) Home() {
	ac.Ctx.WriteString("辽宁-沈阳")
}

func (hc *HobbyController) Content() {
	hc.Ctx.WriteString("唱歌-跳舞")
}

// RegisterNamespaceRoutes web命名空间
func RegisterNamespaceRoutes() {
	namespace := web.NewNamespace("/v", web.NSGet("/get", func(ctx *context.Context) {
		ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
	}))

	hc := &HobbyController{}
	ns := web.NewNamespace("/app",
		//函数式路由
		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("绿满山川闻杜宇。便做无情,莫也愁人苦。把酒送春春不语。黄昏却下潇潇雨")
		}),
		//控制风格路由手动形式
		web.NSCtrlGet("/find", (*AddrController).Home),
		//控制风格路由自动形式
		web.NSAutoRouter(hc),
	)

	nsn := web.NewNamespace("/n",
		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("独行独坐,独唱独酬还独卧。伫立伤神,无奈轻寒著摸人")
		}),
		//嵌套命名空间
		web.NSNamespace("/app",
			web.NSGet("/get", func(ctx *context.Context) {
				ctx.WriteString("此情谁见,泪洗残妆无一半。愁病相仍,剔尽寒灯梦不成")
			}),
			web.NSGet("/find", func(ctx *context.Context) {
				ctx.WriteString("夜久无眠秋气清,烛花频剪欲三更")
			}),
		),
	)

	fsn := web.NewNamespace("/f",
		//添加filter
		web.NSBefore(func(ctx *context.Context) {
			fmt.Println(ctx.Request.RequestURI)
			fmt.Println("Before Filter")
		}),

		web.NSGet("/get", func(ctx *context.Context) {
			ctx.WriteString("铺床凉满梧桐月,月在梧桐缺处明")
		}),
	)
	//添加filter
	fsn.Filter("before", func(ctx *context.Context) {
		fmt.Println("Before Filter" + ctx.Request.RequestURI)
	})

	web.AddNamespace(namespace)
	web.AddNamespace(ns)
	web.AddNamespace(nsn)
	web.AddNamespace(fsn)
}

运行效果

目前来说,命名空间(namespace)对 filter 的支持是有限的,想要支持复杂的 filter,或者 filter-chain,需要使用过滤器,过滤器笔者会在后面的文章详细讲解

下一讲:《Beego 使用教程 4:过滤器》

至此完

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世君子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值