使用gin封装一个web脚手架(三):改装路由组

482 阅读2分钟

先看一下这个路由

package routes

//routes/routes.go

import (
	"github.com/gin-gonic/gin"
	"myGin/context"
	"myGin/controller"
	"myGin/response"
)

func Load(r *gin.Engine) {

	api := r.Group("/api")

	user := api.Group("/user")

	user.GET("/info", convert(controller.Index))

}

这种写法的路由组层级关系看的不是很清楚,等后期路由多起来绝对是一个头疼的事情

理想的模式应该是这样

package routes

//routes/routes.go

import (
	"github.com/gin-gonic/gin"
	"myGin/context"
	"myGin/controller"
	"myGin/response"
)

func Load(r *gin.Engine) {



	r.Group("/api", func(api router) {

		api.Group("/user", func(user router) {

			user.GET("/info", convert(controller.Index))
			user.GET("/order", convert(controller.Index))
			user.GET("/money", convert(controller.Index))

		})

	})

}


这要实现一个router模块

在routes文件夹下添加一个router.go文件

package routes

import "github.com/gin-gonic/gin"

type router struct {
	engine *gin.Engine
}

func newRouter(engine *gin.Engine) *router {

	return &router{
		engine: engine,
	}
}

第一步是实例化一个Router对象

调用方是这样

func Load(r *gin.Engine) {

    router:=newRouter(r)

}

下一步是添加路由组,继续在router.go添加

package routes

////routes/router.go

import "github.com/gin-gonic/gin"

type router struct {
	engine *gin.Engine
}

type group struct {
	engine *gin.Engine
	path   string
}

func newRouter(engine *gin.Engine) *router {

	return &router{
		engine: engine,
	}
}

func (r *router) Group(path string, callback func(group)) {

	callback(group{
		engine: r.engine,
		path:   path,
	})

}

调用方

func Load(r *gin.Engine) {

	router := newRouter(r)

	router.Group("/api", func(api group) {

	})

}

group之后也可以继续嵌套

继续实现

package routes

////routes/router.go

import "github.com/gin-gonic/gin"

type router struct {
	engine *gin.Engine
}

type group struct {
	engine *gin.Engine
	path   string
}

func newRouter(engine *gin.Engine) *router {

	return &router{
		engine: engine,
	}
}

func (r *router) Group(path string, callback func(group)) {

	callback(group{
		engine: r.engine,
		path:   path,
	})

}

func (g group) Group(path string, callback func(group)) {

	g.path += path

	callback(g)
}

调用方

func Load(r *gin.Engine) {

	router := newRouter(r)

	router.Group("/api", func(api group) {

		api.Group("/user", func(user group) {

		})

	})

}

最后一步需要实现函数的绑定

package routes

////routes/router.go

import (
	"github.com/gin-gonic/gin"
	"myGin/context"
	"myGin/response"
)

type router struct {
	engine *gin.Engine
}

type group struct {
	engine *gin.Engine
	path   string
}

type method int

const (
	GET    method = 0x000000
	POST   method = 0x000001
	PUT    method = 0x000002
	DELETE method = 0x000003
	ANY    method = 0x000004
)

func newRouter(engine *gin.Engine) *router {

	return &router{
		engine: engine,
	}
}

func (r *router) Group(path string, callback func(group)) {

	callback(group{
		engine: r.engine,
		path:   path,
	})

}

func (g group) Group(path string, callback func(group)) {

	g.path += path

	callback(g)
}

func (g group) Registered(method method, url string, action func(*context.Context) *response.Response) {

	handlerFunc := convert(action)

	finalUrl := g.path + url

	switch method {

	case GET:

		g.engine.GET(finalUrl, handlerFunc)

	case POST:

		g.engine.GET(finalUrl, handlerFunc)

	case PUT:

		g.engine.PUT(finalUrl, handlerFunc)

	case DELETE:

		g.engine.DELETE(finalUrl, handlerFunc)

	case ANY:

		g.engine.Any(finalUrl, handlerFunc)

	}

}

func convert(f func(*context.Context) *response.Response) gin.HandlerFunc {

	return func(c *gin.Context) {

		resp := f(&context.Context{Context: c})

		data := resp.GetData()

		switch item := data.(type) {

		case string:

			c.String(200, item)

		case gin.H:

			c.JSON(200, item)

		}

	}

}

调用方

package routes

//routes/routes.go

import (
	"github.com/gin-gonic/gin"
	"myGin/controller"
)

func Load(r *gin.Engine) {

	router := newRouter(r)

	router.Group("/api", func(api group) {

		api.Group("/user", func(user group) {

			user.Registered(GET, "/info", controller.Index)
			user.Registered(GET, "/order", controller.Index)
			user.Registered(GET, "/money", controller.Index)

		})

	})

}

浏览器访问

image.png