go logo
Go,  技术,  编程语言

从零开始搭建go项目(gin框架)(二) – 规划路由

上一节 从零开始搭建go项目(gin框架)(一) 中,我们已经实现了一个go项目的基础搭建,实现了程序可访问,本节,我们继续对该项目进行完善和补充。

第一步 基础准备

根目录创建 ./library 目录,作为我们的自有库目录

mkdir library

创建错误码定义文件 ./library/error_code.go :

package library

const (
	ErrnoSuccess = 0
	ErrnoError   = 1
	ErrnoUnknown = 2
)
var ErrNoToMsgMap = map[int32]string{
	ErrnoSuccess: "success",
	ErrnoError:   "failed",
	ErrnoUnknown: "unknown",
}
func GetErrMsg(errNo int32) string {
	if errMsg, ok := ErrNoToMsgMap[errNo]; ok {
		return errMsg
	}
	return "unknown error"
}

接口返回体定义(responseBody) ./library/response.go :

package library

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"net/http"
)

type ResponseBody struct {
	Errno int32 `json:"errno"`
	Msg string `json:"msg"`
	Data interface{} `json:"data"`
}

func NewResponseBody() *ResponseBody {
	return &ResponseBody{
		Errno: ErrnoSuccess,
		Msg: GetErrMsg(ErrnoSuccess),
		Data: map[string]interface{}{},
	}
}

func (res *ResponseBody) SetData(data interface{})  {
	res.Data = data
}

func (res *ResponseBody) SetErrNo(errNo int32)  {
	res.Errno = errNo
}

func (res *ResponseBody) SetErrMsg(errMsg string)  {
	res.Msg = errMsg
}

func RecoverResponse(ctx *gin.Context, responseBody *ResponseBody)  {
	// panic
	if err := recover(); err != nil {
		responseBody.SetErrNo(ErrnoUnknown)
	}
	resp, err := json.Marshal(responseBody)
	if err != nil {
		ctx.Data(http.StatusOK, "application/json;charset=utf-8", []byte(`{"errno":1,"msg":"unknown"}`))
	} else {
		ctx.Data(http.StatusOK, "application/json;charset=utf-8", resp)
	}
	return
}

第二步 创建接口

在跟没有了创建 ./service 目录,作为我们的接口业务处理层

./service/user.go :

package service

import (
	"fusheng-admin/library"
	"github.com/gin-gonic/gin"
)

// 请求参数结构体
type UserRequestParams struct {
	Ctx *gin.Context
}

func UserAdd(param *UserRequestParams, responseBody *library.ResponseBody)  {
	return
}

在根目录创建./api/v1目录,作为我们的接口目录:

mkdir -p api/v1

创建接口 ./api/v1/user.go :

package v1

import (
	"fusheng-admin/library"
	"fusheng-admin/service"
	"github.com/gin-gonic/gin"
)

func UserAdd(ctx *gin.Context)  {
	responseBody := library.NewResponseBody()
	defer library.RecoverResponse(ctx, responseBody)
	param := &service.UserRequestParams{Ctx: ctx}
	ctx.BindJSON(param)
	service.UserAdd(param, responseBody)
}

第三步 定义接口路由

根目录创建router目录,目录下创建router.go路由文件

./router/router.go :

package router

import (
	"fusheng-admin/api/v1"
	"github.com/gin-gonic/gin"
)

func Http(router *gin.Engine)  {
	apiRouter := router.Group("/api/v1/")
	{
		apiRouter.POST("/useradd", v1.UserAdd)
	}
}

ps: 此处我们定义了一个接口,http://127.0.0.1:8088/api/v1/useradd, 该接口的处理逻辑为 v1.UserAdd函数

路由规则可以参考 grouping-routes , v1是v1版本的意思,之所以这样设置,是因为对外提供的接口,后期经常是有版本迭代的需求的,这样的话,方便以后对外提供多个版本的接口。

第四步 入口接入路由

修改main.go文件,替换掉原来的路由:

修改后的main.go

package main

import (
	"fusheng-admin/router"
	"github.com/gin-gonic/gin"
)

func main()  {
	// 1.创建路由
	r := gin.Default()

	// 2.绑定路由规则,执行的函数
	// gin.Context,封装了request和response
	router.Http(r)

	// 3.监听端口,默认在8080
	// Run("里面不指定端口号默认为8088")
	r.Run(":8088")
}

第五步 测试

因为我们路由中,该接口定义的是只接受POST请求,所以只能post方式才可以请求通接口

如果想要接受GET请求的话,只需将POST改为GET即可,或者也可改为Any, Any可同时接受get和post请求

第六步 总结

至此,一个简单的接口,我们就已经实现了。

本节中,我们首先是实现了路由控制,以及基础的接口返回以及错误码这几个框架层面上的基础功能模块。这些模块抽象出来后,可以极大的简化我们日后的具体的业务逻辑开发,使得开发时无需再去关心这些。

其次,大家应该也注意到,在api/v1/user.go中,接受参数时,我们是通过一个参数结构体来接收的:

param := &service.UserRequestParams{Ctx: ctx}
ctx.BindJSON(param)
// 请求参数结构体
type UserRequestParams struct {
	Ctx *gin.Context
}

这样的做法,一方面是规范了我们的接口参数的字段与类型,另一方面也起到了接口参数检查的作用,同时如果后续调用该参数,可以直接调用,更加的方便。

第八步 参考文档

https://github.com/gin-gonic/gin


精品课程


guest

1 评论
最新
最旧 最多投票
内联反馈
查看所有评论
匿名

不错