Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add http extension for go-zero #1

Merged
merged 6 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/
.idea
.DS_Store
20 changes: 20 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '3'

vars:
MODULE: x

tasks:
goimportx:
deps:
- setup:goimportx
cmds:
- 'for file in {{.CLI_ARGS}}; do
goimportx --group "system,others" --file $file -w;
done'
setup:goimportx:
cmds:
- go install github.com/anqiansong/goimportx@latest
status:
- test -f goimportx


19 changes: 19 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package errors

import "fmt"

// CodeMsg is a struct that contains a code and a message.
// It implements the error interface.
type CodeMsg struct {
Code int
Msg string
}

func (c *CodeMsg) Error() string {
return fmt.Sprintf("code: %d, msg: %s", c.Code, c.Msg)
}

// New creates a new CodeMsg.
func New(code int, msg string) error {
return &CodeMsg{Code: code, Msg: msg}
}
26 changes: 26 additions & 0 deletions errors/errors_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package errors

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestNew(t *testing.T) {
ast := assert.New(t)
c := New(1, "test")
cm, ok := c.(*CodeMsg)
ast.True(ok)
ast.NotNil(cm)
ast.Equal(int(1), cm.Code)
ast.Equal("test", cm.Msg)
}

func TestCodeMsg_Error(t *testing.T) {
ast := assert.New(t)
c := New(1, "test")
cm, ok := c.(*CodeMsg)
ast.True(ok)
ast.NotNil(cm)
ast.NotEmpty(cm.Error())
}
54 changes: 54 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module github.com/zeromicro/x

go 1.18

require (
github.com/stretchr/testify v1.8.2
github.com/zeromicro/go-zero v1.5.1
google.golang.org/grpc v1.54.0
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/openzipkin/zipkin-go v0.4.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/automaxprocs v1.5.2 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
604 changes: 604 additions & 0 deletions go.sum

Large diffs are not rendered by default.

82 changes: 82 additions & 0 deletions http/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package http

import (
"context"
"encoding/xml"
"net/http"

"github.com/zeromicro/go-zero/rest/httpx"
"github.com/zeromicro/x/errors"
"google.golang.org/grpc/status"
)

// BaseResponse is the base response struct.
type BaseResponse[T any] struct {
// Code represents the business code, not the http 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 http.StatusOK.
func JsonBaseResponse(w http.ResponseWriter, v any) {
httpx.OkJson(w, wrapBaseResponse(v))
}

// JsonBaseResponseCtx writes v into w with http.StatusOK.
func JsonBaseResponseCtx(ctx context.Context, w http.ResponseWriter, v any) {
httpx.OkJsonCtx(ctx, w, wrapBaseResponse(v))
}

// XmlBaseResponse writes v into w with http.StatusOK.
func XmlBaseResponse(w http.ResponseWriter, v any) {
OkXml(w, wrapXmlBaseResponse(v))
}

// XmlBaseResponseCtx writes v into w with http.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 error:
resp.Code = BusinessCodeError
resp.Msg = data.Error()
default:
resp.Code = BusinessCodeOK
resp.Msg = BusinessMsgOk
resp.Data = v
}

return resp
}
Loading