使用gin封装一个web脚手架(一):控制器和路由

2,386 阅读2分钟

创建一个go项目,名称为myGin

go.mod文件为

module myGin

go 1.16

安装gin

go get -u github.com/gin-gonic/gin

创建一个main.go文件

package main

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

func main() {
	r := gin.Default()

	r.Run()
}

创建routes文件夹和controller

项目结构为

image.png

在controller下创建一个Index控制器

package controller

//controller/Index.go

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

func Index(context *gin.Context) {

	context.JSON(200, gin.H{"msg": "hello world"})
}

在routes文件夹下创建routes.go,用来加载整个项目的路由

package routes

//routes/routes.go

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

func Load(r *gin.Engine) {

	r.GET("/", controller.Index)

}

在main.go调用加载路由函数

package main

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

func main() {
	r := gin.Default()

	routes.Load(r)

	r.Run()
}

运行浏览器,访问http://127.0.0.1:8080

image.png


到这里,控制器和路由已经被拆分开来了,但是有一个问题,如果控制器的代码如下
package controller

//controller/Index.go

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

func Index(context *gin.Context) {

	if 1+1 == 2 {

		context.JSON(200, gin.H{"msg": "hello world"})
	}

	context.JSON(200, gin.H{"msg": "hello world"})
}

浏览器访问

image.png

出现了两个结果,正确的写法应该是

package controller

//controller/Index.go

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

func Index(context *gin.Context) {

	if 1+1 == 2 {

		context.JSON(200, gin.H{"msg": "hello world"})

		return
	}

	context.JSON(200, gin.H{"msg": "hello world"})
}

判断语句忘记了return就会出现这种问题,实际开发中难免会犯这种错误

和传统web框架相比,gin的控制器缺少了一个返回值(response)

现在改装一下控制器,让它支持返回值

在项目下新建一个response文件夹并创建response.go文件

package response

//response/response.go

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

type Response struct {
	data interface{}
}

func Resp() *Response {

	return &Response{}
}

func (r *Response) Json(data gin.H) *Response {

	r.data = data

	return r
}

func (r *Response) String(data string) *Response {

	r.data = data

	return r
}

func (r *Response) Byte(data []byte) *Response {

	r.data = data

	return r
}

func (r *Response) GetData() interface{} {

	return r.data
}

修改index控制器

package controller

//controller/Index.go

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

func Index(context *gin.Context) *response.Response {

	if 1+1 == 2 {

		return response.Resp().Json(gin.H{"msg": "hello world"})

	}

	return response.Resp().Json(gin.H{"msg": "hello world"})
}

回到路由,路由的处理函数需要返回gin.HandlerFunc类型,写一个函数转换一下

package routes

//routes/routes.go

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

func Load(r *gin.Engine) {

	r.GET("/", convert(controller.Index))

}

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

	return func(c *gin.Context) {

		resp := f(c)

		data := resp.GetData()

		switch item := data.(type) {

		case string:

			c.String(200, item)

		case gin.H:

			c.JSON(200, item)

		}

	}

}

访问浏览器

image.png

完成