Group routing is the primary routing registration method used in business projects.
Group Routing
The GoFrame
framework supports group routing registration. You can specify a prefix
for a group route (you can also directly specify the /
prefix, which means registering under the root route), and all route registrations under this group will be registered under this route prefix. Group routing registration is also the recommended routing registration method.
API Documentation: https://pkg.go.dev/github.com/gogf/gf/v2/net/ghttp#RouterGroup
// Create a group route
func (s *Server) Group(prefix string, groups ...func(g *RouterGroup)) *RouterGroup
// Register Method route
func (g *RouterGroup) ALL(pattern string, object interface{}, params...interface{})
func (g *RouterGroup) GET(pattern string, object interface{}, params...interface{})
func (g *RouterGroup) PUT(pattern string, object interface{}, params...interface{})
func (g *RouterGroup) POST(pattern string, object interface{}, params...interface{})
func (g *RouterGroup) DELETE(pattern string, object interface{}, params...interface{})
...
// Middleware binding
func (g *RouterGroup) Middleware(handlers ...HandlerFunc) *RouterGroup
// Batch registration
func (g *RouterGroup) Map(m map[string]interface{})
func (g *RouterGroup) ALLMap(m map[string]interface{})
Brief Introduction:
- The
Group
method is used to create a group route object and supports creating on a specified domain object. - Methods named after
HTTP Method
are used to bind specifiedHTTP Method
routes; theALL
method is used to register allHTTP Methods
to a specified function/object/controller; theREST
method is used to registerRESTful
style routes, requiring a given executable object or controller object. - The
Middleware
method is used to bind one or more middleware to the routes of the current group, as detailed in the middleware chapter.
Simple Example
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.Group("/api", func(group *ghttp.RouterGroup) {
group.ALL("/all", func(r *ghttp.Request) {
r.Response.Write("all")
})
group.GET("/get", func(r *ghttp.Request) {
r.Response.Write("get")
})
group.POST("/post", func(r *ghttp.Request) {
r.Response.Write("post")
})
})
s.SetPort(8199)
s.Run()
}
After execution, the terminal prints out the routing table as follows:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|-----------|-----------------|------------|
default | default | :8199 | ALL | /api/all | main.main.func1 |
|---------|---------|---------|--------|-----------|-----------------|------------|
default | default | :8199 | GET | /api/get | main.main.func2 |
|---------|---------|---------|--------|-----------|-----------------|------------|
default | default | :8199 | POST | /api/post | main.main.func3 |
|---------|---------|---------|--------|-----------|-----------------|------------|
Among them, /api/get
only allows access via GET
, /api/post
only allows access via POST
, and /api/all
allows access via all methods.
We use the curl
tool for testing:
/api/get
$ curl http://127.0.0.1:8199/api/get
get
$ curl -X POST http://127.0.0.1:8199/api/get
Not Found
/api/post
$ curl http://127.0.0.1:8199/api/post
Not Found
$ curl -X POST http://127.0.0.1:8199/api/post post
/api/all
$ curl http://127.0.0.1:8199/api/all
all
$ curl -X POST http://127.0.0.1:8199/api/all
all
$ curl -X DELETE http://127.0.0.1:8199/api/all
all
$ curl -X OPTIONS http://127.0.0.1:8199/api/all
all
Hierarchical Registration
The hierarchical routing registration method of the GoFrame
framework is inspired by the PHP Laravel
framework.
It is recommended to use hierarchical route registration; the registered route code is clearer and more intuitive. The GoFrame
framework's group routing registration supports a more intuitive and elegant hierarchical registration method for developers to manage route lists more conveniently. Hierarchical route registration is also the recommended routing registration method. Let's look at a more comprehensive example where middleware, HOOK
, and routes bound to different HTTP Methods
are used:
package main
import (
"fmt"
"net/http"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func MiddlewareAuth(r *ghttp.Request) {
if r.Get("token").String() != "123456" {
r.Response.WriteStatus(http.StatusForbidden)
return
}
r.Middleware.Next()
}
func MiddlewareCORS(r *ghttp.Request) {
r.Response.CORSDefault()
r.Middleware.Next()
}
func MiddlewareLog(r *ghttp.Request) {
r.Middleware.Next()
fmt.Println(r.Response.Status, r.URL.Path)
}
func main() {
s := g.Server()
s.Use(MiddlewareLog)
s.Group("/api.v2", func(group *ghttp.RouterGroup) {
group.Middleware(MiddlewareAuth, MiddlewareCORS)
group.GET("/test", func(r *ghttp.Request) {
r.Response.Write("test")
})
group.Group("/order", func(group *ghttp.RouterGroup) {
group.GET("/list", func(r *ghttp.Request) {
r.Response.Write("list")
})
group.PUT("/update", func(r *ghttp.Request) {
r.Response.Write("update")
})
})
group.Group("/user", func(group *ghttp.RouterGroup) {
group.GET("/info", func(r *ghttp.Request) {
r.Response.Write("info")
})
group.POST("/edit", func(r *ghttp.Request) {
r.Response.Write("edit")
})
group.DELETE("/drop", func(r *ghttp.Request) {
r.Response.Write("drop")
})
})
group.Group("/hook", func(group *ghttp.RouterGroup) {
group.Hook("/*", ghttp.HookBeforeServe, func(r *ghttp.Request) {
r.Response.Write("hook any")
})
group.Hook("/:name", ghttp.HookBeforeServe, func(r *ghttp.Request) {
r.Response.Write("hook name")
})
})
})
s.SetPort(8199)
s.Run()
}
After execution, the registered route list looks like this:
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | ALL | /* | main.MiddlewareLog | GLOBAL MIDDLEWARE
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | ALL | /api.v2/hook/* | main.main.func1.4.1 | HOOK_BEFORE_SERVE
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | ALL | /api.v2/hook/:name | main.main.func1.4.2 | HOOK_BEFORE_SERVE
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | GET | /api.v2/order/list | main.main.func1.2.1 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | PUT | /api.v2/order/update | main.main.func1.2.2 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | GET | /api.v2/test | main.main.func1.1 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | DELETE | /api.v2/user/drop | main.main.func1.3.3 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | POST | /api.v2/user/edit | main.main.func1.3.2 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
default | default | :8199 | GET | /api.v2/user/info | main.main.func1.3.1 | main.MiddlewareAuth,main.MiddlewareCORS
|---------|---------|---------|--------|----------------------|---------------------|-----------------------------------------|
Batch Registration
Map
The Map
method can be used for batch group route registration, but for the same URI
with different HTTP Methods
, you need to specify the HTTP Method
according to route conventions. Example usage:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func UserGet(r *ghttp.Request) {
r.Response.Write("get")
}
func UserDelete(r *ghttp.Request) {
r.Response.Write("delete")
}
func main() {
s := g.Server()
s.Group("/api", func(group *ghttp.RouterGroup) {
group.Map(g.Map{
"GET: /user": UserGet,
"DELETE: /user": UserDelete,
})
})
s.SetPort(8199)
s.Run()
}
AllMap
You can also use the ALLMap
method for batch group route registration. Routes registered through this method will apply the route function/object to all HTTP Methods
. Example usage:
s := g.Server()
// Routing registration for the front-end system
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(service.Middleware.Ctx)
group.ALLMap(g.Map{
"/": api.Index, // Home
"/login": api.Login, // Login
"/register": api.Register, // Register
"/category": api.Category, // Category
"/topic": api.Topic, // Topic
"/topic/:id": api.Topic.Detail, // Topic - Detail
"/ask": api.Ask, // Q&A
"/ask/:id": api.Ask.Detail, // Q&A - Detail
"/article": api.Article, // Article
"/article/:id": api.Article.Detail, // Article - Detail
"/reply": api.Reply, // Reply
"/search": api.Search, // Search
"/captcha": api.Captcha, // Captcha
"/user/:id": api.User.Index, // User - Home
})
// Permission control routes
group.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(service.Middleware.Auth)
group.ALLMap(g.Map{
"/user": api.User, // User
"/content": api.Content, // Content
"/interact": api.Interact, // Interact
"/file": api.File, // File
})
})
})