go-zero統一Response的返回值

jsonMark發表於2021-12-30

官方參考資料

參考1:官網的【模板管理】=》【自定義模板】

go-zero.dev/cn/template.html

參考2:官網的【專案開發】=》【業務開發】=》【錯誤處理】

go-zero.dev/cn/error-handle.html

步驟一:新建立自己的錯誤處理相關函式

【說明】:你拿去使用,需要將”go-slot/utils/errorx”等import路徑改成你自己實際的路徑。我當前專案名稱叫go-slot,utils是我的一個工具包。

1.官方給的程式碼:


package response

import (

 "net/http"

 "github.com/tal-tech/go-zero/rest/httpx"

)

type  Body  struct {

Code int  `json:"code"`

    Msg  string `json:"msg"`

Data interface{} `json:"data,omitempty"`

}

func  Response(w http.ResponseWriter, resp interface{}, err error) {

 var  body Body

 if err != nil {

 body.Code = -1

 body.Msg = err.Error()

} else {

 body.Msg = "OK"

 body.Data = resp

    }

    httpx.OkJson(w, body)

}
  1. 我此時修改的程式碼目錄如下,程式碼拿去,需要你自己修改相關的import資訊,小呆瓜別直接用

//baseerror.go和response.go的路徑

utils

├─ common.go

├─ errorx

│  └─ baseerror.go

├─ http_rpc.go

├─ md5.go

└─ response

   └─ response.go

2.1. utils/response/response.go程式碼如下:


//utils/response/response.go程式碼

package response

import (

 "github.com/tal-tech/go-zero/rest/httpx"

 "go-slot/utils/errorx"

 "net/http"

)

type  Body  struct {

Code int  `json:"code"`

    Message  string `json:"msg"`

Data interface{} `json:"data,omitempty"`

}

//統一封裝成功響應值

func  Response(w http.ResponseWriter, resp interface{}, err error) {

 var  body Body

 if err != nil {

 switch  e := err.(type) {

 case *errorx.CodeError://業務輸出錯誤

 body.Code = e.Code

 body.Message = e.Message

 body.Data = e.Data

 //body.Data = e.Data()

 default: //系統未知錯誤

 body.Code = 1

 body.Message = err.Error()

        }

} else {

 body.Code = 0

 body.Message = "請求成功!"

 body.Data = resp

    }

    httpx.OkJson(w, body)

}

2.2. utils/errorx/baseerror.go程式碼如下:


package errorx

//定義錯誤型別

const  defaultCode = 1001

type  CodeError  struct {

    Code    int `json:"code"`

Message string  `json:"message"`

Data interface{} `json:"data,omitempty"`

}

func  NewCodeError(code int, msg string) error {

 return &CodeError{Code: code, Message: msg}

}

func  NewErrorData(code int, msg string,data interface{}) error {

 return &CodeError{Code: code, Message: msg, Data: data}

}

func  NewDefaultError(msg string) error {

 return  NewCodeError(defaultCode, msg)

}

func (e *CodeError) Error() string {

 return e.Message

}

//------------------Response響應值----------------------

//func (e *CodeError) Info()響應返回值

type  CodeErrorResponse  struct {

    Code    int `json:"code"`

Message string  `json:"message"`

Data interface{} `json:"data,omitempty"`

}

//返回相關引數

func (e *CodeError) Info() *CodeErrorResponse {

 return &CodeErrorResponse{

        Code:    e.Code,

        Message: e.Message,

        Data:   e.Data,

    }

}

步驟二:生成本地goctl快取模板

1.隨機開啟一個CMD視窗使用模板初始化命令goctl template init進行初始化,如果本地沒有~/.goctl/api/handler.tpl檔案 的話。

mac環境對應的路徑就是~/.goctl/api。

window路徑會是C:\Users\【你的電腦使用者名稱】.goctl,此時我的模板路徑是C:\Users\DELL.goctl\1.2.3-cli\api,其中DELL是此時的使用者名稱。

goctl完整模板結構如下:


.goctl

└─ 1.2.3-cli

   ├─ api

   │  ├─ config.tpl

   │  ├─ context.tpl

   │  ├─ etc.tpl

   │  ├─ handler.tpl

   │  ├─ handler官方模板.tpl

   │  ├─ logic.tpl

   │  ├─ main.tpl

   │  └─ template.tpl

   ├─ docker

   │  └─ docker.tpl

   ├─ kube

   │  ├─ deployment.tpl

   │  └─ job.tpl

   ├─ model

   │  ├─ delete.tpl

   │  ├─ err.tpl

   │  ├─ field.tpl

   │  ├─ find-one-by-field-extra-method.tpl

   │  ├─ find-one-by-field.tpl

   │  ├─ find-one.tpl

   │  ├─ import-no-cache.tpl

   │  ├─ import.tpl

   │  ├─ insert.tpl

│  ├─ interface-delete.tpl

│  ├─ interface-find-one-by-field.tpl

│  ├─ interface-find-one.tpl

│  ├─ interface-insert.tpl

│  ├─ interface-update.tpl

   │  ├─ model-new.tpl

   │  ├─ model.tpl

   │  ├─ tag.tpl

   │  ├─ types.tpl

   │  ├─ update.tpl

   │  └─ var.tpl

   ├─ mongo

   │  ├─ err.tpl

   │  └─ model.tpl

   ├─ newapi

   │  └─ newtemplate.tpl

   └─ rpc

      ├─ call-func.tpl

      ├─ call-interface-func.tpl

      ├─ call.tpl

      ├─ config.tpl

      ├─ etc.tpl

      ├─ logic-func.tpl

      ├─ logic.tpl

      ├─ main.tpl

      ├─ server-func.tpl

      ├─ server.tpl

      ├─ svc.tpl

      └─ template.tpl

步驟三:修改goctl的handel模板

【說明】:你拿去使用需要修改import

3.1. 官方預設的handel模板


package {{.PkgName}}

import (

 "net/http"

    {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}}

    {{.ImportPackages}}

)

func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {

 return  func(w http.ResponseWriter, r *http.Request) {

        {{if .HasRequest}}var  req types.{{.RequestType}}

 if  err := httpx.Parse(r, &req); err != nil {

            httpx.Error(w, err)

 return

        }

        {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), ctx)

        {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})

 if err != nil {

            httpx.Error(w, err)

} else {

            {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}}

        }

    }

}

3.2. 我修改之後的handel模板完整程式碼


package {{.PkgName}}

import (

 "go-slot/utils/response"

 "net/http"

    {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}}

    {{.ImportPackages}}

)

func {{.HandlerName}}(ctx *svc.ServiceContext) http.HandlerFunc {

 return  func(w http.ResponseWriter, r *http.Request) {

        {{if .HasRequest}}var  req types.{{.RequestType}}

 if  err := httpx.Parse(r, &req); err != nil {

            httpx.Error(w, err)

 return

        }

        {{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), ctx)

        {{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}req{{end}})

        {{if .HasResp}}response.Response(w, resp, err){{else}}response.Response(w, nil, err){{end}}

    }

}

其實就是做了2件事情。

第1件事:刪除官方模板的如下程式碼


 if err != nil {

            httpx.Error(w, err)

} else {

            {{if .HasResp}}httpx.OkJson(w, resp){{else}}httpx.Ok(w){{end}}

        }

第2件事:新增如下程式碼,其中


{{if .HasResp}}response.Response(w, resp, err){{else}}response.Response(w, nil, err){{end}}

//注意匯入你自己response.Response對應的import

步驟四:去任意一個logic的方法驗證結果


//記得import自己對應的路徑

err := errorx.NewDefaultError("新增會員地址失敗") //預設code錯誤

err := errorx.NewErrorData(400,"錯誤","資料錯誤") //指定任意錯誤data資訊

err := errorx.NewCodeError(400,"錯誤") //指定code和message資訊
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章