- /internal/server/http.go
自定义:响应格式、错误
go
opts = append(opts, http.ResponseEncoder(responseEncoder))
opts = append(opts, http.ErrorEncoder(errorEncoder))
- /internal/server/httpencoder.go
上面的:自定义内容,写在下面
go
package server
import (
"net/http"
kratoshttp "github.com/go-kratos/kratos/v2/transport/http"
karatosstatus "github.com/go-kratos/kratos/v2/transport/http/status"
"google.golang.org/grpc/status"
)
type httpResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data any `json:"data"`
}
func responseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
if v == nil {
return nil
}
if rd, ok := v.(kratoshttp.Redirector); ok {
url, code := rd.Redirect()
http.Redirect(w, r, url, code)
return nil
}
codec, _ := kratoshttp.CodecForRequest(r, "Accept")
res := &httpResponse{
Code: http.StatusOK,
Msg: "success",
Data: v,
}
data, err := codec.Marshal(res)
if err != nil {
return err
}
w.Header().Set("Content-Type", "application/" + codec.Name())
_, err = w.Write(data)
if err != nil {
return err
}
return nil
}
// ⾃自定义的错误响应编码器器
func errorEncoder(w http.ResponseWriter, r *http.Request, err error) {
if err == nil {
return
}
resp := new(httpResponse)
// 能从err⾥里里⾯面解析出错误码的
if gs, ok := status.FromError(err); ok {
resp = &httpResponse{
Code: karatosstatus.FromGRPCCode(gs.Code()),
Msg: gs.Message(),
Data: nil,
}
} else {
resp = &httpResponse{
Code: http.StatusInternalServerError, // 500
Msg: "内部错误",
}
}
codec, _ := kratoshttp.CodecForRequest(r, "Accept")
body, err := codec.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/"+codec.Name())
w.WriteHeader(resp.Code)
_, _ = w.Write(body)
}
- /api/bubble/v1/todo_error.proto
自定义状态码
①、安装依赖:go install github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2@latest
②、定义好proto后,windows执行生成命令
protoc --proto_path=. --proto_path=./third_party --go_out=paths=source_relative:. --go-errors_out=paths=source_relative:. api/bubble/v1/todo_error.proto
go
syntax = "proto3";
package api.bubble.v1;
import "errors/errors.proto";
option go_package = "bubble/api/bubble/v1;v1";
option java_multiple_files = true;
option java_package = "api.bubble.v1";
enum ErrorReason {
// 设置缺省错误码
option (errors.default_code) = 500;
// 为某个枚举单独设置错误码
TODO_NOT_FOUND = 0 [(errors.code) = 404];
INVALID_PARAM = 1 [(errors.code) = 400];
}