这篇文章主要介绍“企业项目迁移go-zero的方法教程”,在日常操作中,相信很多人在企业项目迁移go-zero的方法教程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”企业项目迁移go-zero的方法教程”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
gateway 中我做了一些自定义,在端请求我们后台接口情况下,虽然多数情况是不需要关心错误码的,但是避免不了要某些场景还是需要根据固定错误码去做特殊处理,我自己定义了一个错误类,这个错误类只在 gateway 中使用:
err.go:
package xerr
import "fmt"
type CodeError struct {
errCode int
errMsg string
}
// 属性
func (e *CodeError) GetErrCode() int {
return e.errCode
}
func (e *CodeError) GetErrMsg() string {
return e.errMsg
}
func (e *CodeError) Error() string {
return fmt.Sprintf("ErrCode:%d,ErrMsg:%s", e.errCode, e.errMsg)
}
func New(errCode int, errMsg string) *CodeError {
return &CodeError{errCode: errCode, errMsg: errMsg}
}
func NewErrCode(errCode int) *CodeError {
return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode)}
}
func NewErrMsg(errMsg string) *CodeError {
return &CodeError{errCode: BAD_REUQEST_ERROR, errMsg: errMsg}
}
errmsg.go
package xerr
var message map[int]string
func init() {
message = make(map[int]string)
message[OK] = "SUCCESS"
message[BAD_REUQEST_ERROR] = "服务器繁忙,请稍后再试"
message[REUQES_PARAM_ERROR] = "参数错误"
message[USER_NOT_FOUND] = "用户不存在"
}
func MapErrMsg(errcode int) string {
if msg, ok := message[errcode]; ok {
return msg
} else {
return "服务器繁忙,请稍后再试"
}
}
errcode.go
package xerr
// 成功返回
const OK = 200
// 全局错误码
// 前3位代表业务,后三位代表具体功能
const BAD_REUQEST_ERROR = 100001
const REUQES_PARAM_ERROR = 100002
// 用户模块
const USER_NOT_FOUND = 200001
我将三个文件统一放在 lib/xerr
目录
有了错误码还不行,还要定义统一返回http的结果,goctl
生成的默认的是挺好的,但是没法符合我这种返回自定义错误码需求,于是我自己有写了一个统一返回结果的文件:
httpresult:
package xhttp
import (
"fishtwo/lib/xerr"
"fmt"
"github.com/tal-tech/go-zero/core/logx"
"github.com/tal-tech/go-zero/rest/httpx"
"google.golang.org/grpc/status"
"net/http"
"github.com/pkg/errors"
)
// http方法
func HttpResult(r *http.Request,w http.ResponseWriter,resp interface{},err error) {
if err == nil {
// 成功返回
r:= Success(resp)
httpx.WriteJson(w, http.StatusOK, r)
} else {
// 错误返回
errcode := xerr.BAD_REUQEST_ERROR
errmsg := "服务器繁忙,请稍后再试"
if e,ok := err.(*xerr.CodeError);ok{
// 自定义CodeError
errcode = e.GetErrCode()
errmsg = e.GetErrMsg()
} else {
originErr := errors.Cause(err) // err类型
if gstatus, ok := status.FromError(originErr);ok{
// grpc err错误
errmsg = gstatus.Message()
}
}
logx.WithContext(r.Context()).Error("【GATEWAY-SRV-ERR】 : %+v ",err)
httpx.WriteJson(w, http.StatusBadRequest, Error(errcode,errmsg))
}
}
// http参数错误返回
func ParamErrorResult(r *http.Request,w http.ResponseWriter,err error) {
errMsg := fmt.Sprintf("%s ,%s", xerr.MapErrMsg(xerr.REUQES_PARAM_ERROR), err.Error())
httpx.WriteJson(w, http.StatusBadRequest, Error(xerr.REUQES_PARAM_ERROR,errMsg))
}
responsebean
package xhttp
type (
NullJson struct {}
ResponseSuccessBean struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
)
func Success(data interface{}) *ResponseSuccessBean {
return &ResponseSuccessBean{200, "OK", data}
}
type ResponseErrorBean struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func Error(errCode int,errMsg string) *ResponseErrorBean {
return &ResponseErrorBean{errCode, errMsg}
}
放在 lib/xhttp下
然后改造了internal/handler/下通过goctl生成的代码:
当然你会说,每次生成完都要手动去改,好麻烦!
当当当当~~~ goctl
的 template
来咯 https://www.yuque.com/tal-tech/go-zero/mkpuit
然后修改 ~/.goctl/api/handler.tpl
:
package handler
import (
"net/http"
{{.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 {
xhttp.ParamErrorResult(r,w,err)
return
}{{end}}
l := logic.New{{.LogicType}}(r.Context(), ctx)
resp, err := l.Login(req)
xhttp.HttpResult(r,w,resp,err)
}
}
在重新生成看看,是不是就 beautiful
了,哈哈
然后在说我们的 gateway log
,如果眼神好的用户,在上面的 httpresult.go
中已经看到了 log
的身影:
是的是的,这样处理就可以啦,这样只要有错误就会打印日志了,go-zero
已经把 trace-id
带进去了,啥?trace-id
不知道是啥?嗯,其实就是把一次请求通过此 id
串联起来,比如你 user-api
调用 user->srv
或者其他 srv
,那要把他们这一次请求都串联起来,需要一个唯一标识别,这个 id
就是做这个,做链路追踪有很多,比如 jaeger
、zipkin
。
model
:rpc
服务中,官方文档推荐是将 model
放在 services
目录下,与每个 rpc
服务一层,但是个人感觉每个 model
对应一张表,一张表只能由一个服务去控制,哪个服务控制这张表就哪个服务拥有控制这个 model
权利,其他服务想访问就要通过 grpc
,这是个人的想法,所以我把每个服务自己管控的 model
放在了 internal
中
enum
:另外我在服务下加了 enum
枚举目录,因为其他 rpc
服务或者 api
服务会调用这个枚举去比对,我就放在 internal
外部
到此,关于“企业项目迁移go-zero的方法教程”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/kevwan/blog/4922820