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


