🏗️ microservice fabric splitting
This commit is contained in:
85
common/xhttp/base.go
Normal file
85
common/xhttp/base.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package xhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/common/errors"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// BaseResponse is the base response struct.
|
||||
type BaseResponse[T any] struct {
|
||||
// Code represents the business code, not the xhttp status code.
|
||||
Code int `json:"code" xml:"code"`
|
||||
// Msg represents the business message, if Code = BusinessCodeOK,
|
||||
// and Msg is empty, then the Msg will be set to BusinessMsgOk.
|
||||
Msg string `json:"msg" xml:"msg"`
|
||||
// Data represents the business data.
|
||||
Data T `json:"data,omitempty" xml:"data,omitempty"`
|
||||
}
|
||||
|
||||
type baseXmlResponse[T any] struct {
|
||||
XMLName xml.Name `xml:"xml"`
|
||||
Version string `xml:"version,attr"`
|
||||
Encoding string `xml:"encoding,attr"`
|
||||
BaseResponse[T]
|
||||
}
|
||||
|
||||
// JsonBaseResponse writes v into w with xhttp.StatusOK.
|
||||
func JsonBaseResponse(w http.ResponseWriter, v any) {
|
||||
httpx.OkJson(w, wrapBaseResponse(v))
|
||||
}
|
||||
|
||||
// JsonBaseResponseCtx writes v into w with xhttp.StatusOK.
|
||||
func JsonBaseResponseCtx(ctx context.Context, w http.ResponseWriter, v any) {
|
||||
httpx.OkJsonCtx(ctx, w, wrapBaseResponse(v))
|
||||
}
|
||||
|
||||
// XmlBaseResponse writes v into w with xhttp.StatusOK.
|
||||
func XmlBaseResponse(w http.ResponseWriter, v any) {
|
||||
OkXml(w, wrapXmlBaseResponse(v))
|
||||
}
|
||||
|
||||
// XmlBaseResponseCtx writes v into w with xhttp.StatusOK.
|
||||
func XmlBaseResponseCtx(ctx context.Context, w http.ResponseWriter, v any) {
|
||||
OkXmlCtx(ctx, w, wrapXmlBaseResponse(v))
|
||||
}
|
||||
|
||||
func wrapXmlBaseResponse(v any) baseXmlResponse[any] {
|
||||
base := wrapBaseResponse(v)
|
||||
return baseXmlResponse[any]{
|
||||
Version: xmlVersion,
|
||||
Encoding: xmlEncoding,
|
||||
BaseResponse: base,
|
||||
}
|
||||
}
|
||||
|
||||
func wrapBaseResponse(v any) BaseResponse[any] {
|
||||
var resp BaseResponse[any]
|
||||
switch data := v.(type) {
|
||||
case *errors.CodeMsg:
|
||||
resp.Code = data.Code
|
||||
resp.Msg = data.Msg
|
||||
case errors.CodeMsg:
|
||||
resp.Code = data.Code
|
||||
resp.Msg = data.Msg
|
||||
case *status.Status:
|
||||
resp.Code = int(data.Code())
|
||||
resp.Msg = data.Message()
|
||||
case interface{ GRPCStatus() *status.Status }:
|
||||
resp.Code = int(data.GRPCStatus().Code())
|
||||
resp.Msg = data.GRPCStatus().Message()
|
||||
case error:
|
||||
resp.Code = BusinessCodeError
|
||||
resp.Msg = data.Error()
|
||||
default:
|
||||
resp.Code = BusinessCodeOK
|
||||
resp.Msg = BusinessMsgOk
|
||||
resp.Data = v
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
100
common/xhttp/responses.go
Normal file
100
common/xhttp/responses.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package xhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// OkXml writes v into w with 200 OK.
|
||||
func OkXml(w http.ResponseWriter, v any) {
|
||||
WriteXml(w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
// OkXmlCtx writes v into w with 200 OK.
|
||||
func OkXmlCtx(ctx context.Context, w http.ResponseWriter, v any) {
|
||||
WriteXmlCtx(ctx, w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
// WriteXml writes v as xml string into w with code.
|
||||
func WriteXml(w http.ResponseWriter, code int, v any) {
|
||||
if err := doWriteXml(w, code, v); err != nil {
|
||||
logx.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteXmlCtx writes v as xml string into w with code.
|
||||
func WriteXmlCtx(ctx context.Context, w http.ResponseWriter, code int, v any) {
|
||||
if err := doWriteXml(w, code, v); err != nil {
|
||||
logx.WithContext(ctx).Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func doWriteXml(w http.ResponseWriter, code int, v any) error {
|
||||
bs, err := xml.Marshal(v)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return fmt.Errorf("marshal xml failed, error: %w", err)
|
||||
}
|
||||
|
||||
w.Header().Set(httpx.ContentType, XmlContentType)
|
||||
w.WriteHeader(code)
|
||||
|
||||
if n, err := w.Write(bs); err != nil {
|
||||
// xhttp.ErrHandlerTimeout has been handled by xhttp.TimeoutHandler,
|
||||
// so it's ignored here.
|
||||
if err != http.ErrHandlerTimeout {
|
||||
return fmt.Errorf("write response failed, error: %w", err)
|
||||
}
|
||||
} else if n < len(bs) {
|
||||
return fmt.Errorf("actual bytes: %d, written bytes: %d", len(bs), n)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OkHTML writes v into w with 200 OK.
|
||||
func OkHTML(w http.ResponseWriter, v string) {
|
||||
WriteHTML(w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
// OkHTMLCtx writes v into w with 200 OK.
|
||||
func OkHTMLCtx(ctx context.Context, w http.ResponseWriter, v string) {
|
||||
WriteHTMLCtx(ctx, w, http.StatusOK, v)
|
||||
}
|
||||
|
||||
// WriteHTML writes v as HTML string into w with code.
|
||||
func WriteHTML(w http.ResponseWriter, code int, v string) {
|
||||
if err := doWriteHTML(w, code, v); err != nil {
|
||||
logx.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteHTMLCtx writes v as HTML string into w with code.
|
||||
func WriteHTMLCtx(ctx context.Context, w http.ResponseWriter, code int, v string) {
|
||||
if err := doWriteHTML(w, code, v); err != nil {
|
||||
logx.WithContext(ctx).Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func doWriteHTML(w http.ResponseWriter, code int, v string) error {
|
||||
|
||||
w.Header().Set(httpx.ContentType, HTMLContentType)
|
||||
w.WriteHeader(code)
|
||||
|
||||
bs := []byte(v)
|
||||
if n, err := w.Write(bs); err != nil {
|
||||
// xhttp.ErrHandlerTimeout has been handled by xhttp.TimeoutHandler,
|
||||
// so it's ignored here.
|
||||
if err != http.ErrHandlerTimeout {
|
||||
return fmt.Errorf("write response failed, error: %w", err)
|
||||
}
|
||||
} else if n < len(bs) {
|
||||
return fmt.Errorf("actual bytes: %d, written bytes: %d", len(bs), n)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
19
common/xhttp/vars.go
Normal file
19
common/xhttp/vars.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package xhttp
|
||||
|
||||
const (
|
||||
xmlVersion = "1.0"
|
||||
xmlEncoding = "UTF-8"
|
||||
|
||||
// BusinessCodeOK represents the business code for success.
|
||||
BusinessCodeOK = 200
|
||||
// BusinessMsgOk represents the business message for success.
|
||||
BusinessMsgOk = "ok"
|
||||
|
||||
// BusinessCodeError represents the business code for error.
|
||||
BusinessCodeError = 500
|
||||
|
||||
// XmlContentType represents the content type for xml.
|
||||
XmlContentType = "application/xml"
|
||||
// HTMLContentType represents the content type for html.
|
||||
HTMLContentType = "text/html;charset=utf-8"
|
||||
)
|
Reference in New Issue
Block a user