Comments (1)
package server
import (
v1 "code_msg_data/api/helloworld/v1"
"code_msg_data/internal/conf"
"code_msg_data/internal/service"
sj "encoding/json"
nt "net/http"
"strings"
"github.com/go-kratos/kratos/v2/encoding"
"github.com/go-kratos/kratos/v2/encoding/json"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/transport/http"
)
// 最终效果
// $ curl http://localhost:8000/helloworld/kvii
// {"code":0,"message":"success","data":{"message":"Hello kvii"}}
// $ curl http://localhost:8000/helloworld/err
// {"code":404,"message":"user not found"}
// NewHTTPServer new an HTTP server.
func NewHTTPServer(c *conf.Server, greeter *service.GreeterService, logger log.Logger) *http.Server {
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
),
http.ErrorEncoder(DefaultErrorEncoder), // <- 关键代码
http.ResponseEncoder(DefaultResponseEncoder), // <- 关键代码
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := http.NewServer(opts...)
v1.RegisterGreeterHTTPServer(srv, greeter)
return srv
}
// DefaultResponseEncoder copy from http.DefaultResponseEncoder
func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
if v == nil {
return nil
}
if rd, ok := v.(http.Redirector); ok {
url, code := rd.Redirect()
nt.Redirect(w, r, url, code)
return nil
}
codec := encoding.GetCodec(json.Name) // ignore Accept Header
data, err := codec.Marshal(v)
if err != nil {
return err
}
bs, _ := sj.Marshal(NewResponse(data))
w.Header().Set("Content-Type", ContentType(codec.Name()))
_, err = w.Write(bs)
if err != nil {
return err
}
return nil
}
// DefaultErrorEncoder copy from http.DefaultErrorEncoder.
func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {
se := FromError(errors.FromError(err)) // change error to BaseResponse
codec := encoding.GetCodec(json.Name) // ignore Accept header
body, err := codec.Marshal(se)
if err != nil {
w.WriteHeader(nt.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", ContentType(codec.Name()))
// w.WriteHeader(int(se.Code)) // ignore http status code
_, _ = w.Write(body)
}
const (
baseContentType = "application"
)
// ContentType returns the content-type with base prefix.
func ContentType(subtype string) string {
return strings.Join([]string{baseContentType, subtype}, "/")
}
func NewResponse(data []byte) BaseResponse {
return BaseResponse{
Code: 0,
Message: "success",
Data: sj.RawMessage(data),
}
}
func FromError(e *errors.Error) *BaseResponse {
if e == nil {
return nil
}
return &BaseResponse{
Code: e.Code,
Message: e.Message,
}
}
type BaseResponse struct {
Code int32 `json:"code"`
Message string `json:"message"`
Data sj.RawMessage `json:"data,omitempty"`
}
from kratos.
Related Issues (20)
- [Feature] consule register need suport tags[] HOT 2
- When the App stops, the ctx in the afterStop callback is not available HOT 3
- [Question] How to return other Status Code in a successful HTTP request? HOT 7
- [Feature] Add Unwrap to custom response writer. HOT 3
- [Proposal] config feature roadmap HOT 22
- [Feature] replace kratos metrics with otel metrics HOT 3
- [The modification of header file information of http response does not take effect] ctx.Header().Set("Content-Type", "application/octet-stream") HOT 5
- Package version dependency issue HOT 4
- go generate ./...failed HOT 5
- [Feature]Add svrType related fields in proto to protoc-gen-go-http and http transport HOT 3
- proto file used to build the api document reported an error HOT 1
- consul watch, the server is offline and will not receive any notification HOT 6
- [Feature] Add NewClient method to gRPC Client HOT 3
- [Question] DDD的最佳实践方式?包括CQRS、Clean Architecture、六边形结构 HOT 5
- [Question]请教下kratos如何定义支持上传文件接口? HOT 2
- metrics statistics and usage issues [Question] HOT 5
- `stream` response in proto failed to generate http client HOT 2
- [Feature] Add kratos errors to buf remote plugin HOT 1
- [Question] I modified it based on examples/helloworld and found that client/main.go reported an error when executing. I am not sure if it is a BUG.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kratos.