Git Product home page Git Product logo

Comments (1)

kvii avatar kvii commented on May 26, 2024

answer reference

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.