上一节 从零开始搭建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 }
这样的做法,一方面是规范了我们的接口参数的字段与类型,另一方面也起到了接口参数检查的作用,同时如果后续调用该参数,可以直接调用,更加的方便。