mirror of
https://gitee.com/johng/gf
synced 2026-07-08 14:39:50 +08:00
Merge branch 'develop'
This commit is contained in:
@ -23,7 +23,7 @@ type (
|
||||
SrcFolder string `short:"s" name:"srcFolder" brief:"source folder path to be parsed. default: internal/logic" d:"internal/logic"`
|
||||
DstFolder string `short:"d" name:"dstFolder" brief:"destination folder path storing automatically generated go files. default: internal/service" d:"internal/service"`
|
||||
WatchFile string `short:"w" name:"watchFile" brief:"used in file watcher, it generates service go files only if given file is under srcFolder"`
|
||||
StPattern string `short:"a" name:"stPattern" brief:"regular expression matching struct name for generating service. default: s([A-Z]\\w+)" d:"s([A-Z]\\w+)"`
|
||||
StPattern string `short:"a" name:"stPattern" brief:"regular expression matching struct name for generating service. default: s([A-Z]\\\w+)" d:"s([A-Z]\\w+)"`
|
||||
Packages string `short:"p" name:"packages" brief:"produce go files only for given source packages, multiple packages joined with char ','"`
|
||||
ImportPrefix string `short:"i" name:"importPrefix" brief:"custom import prefix to calculate import path for generated importing go file of logic"`
|
||||
OverWrite bool `short:"o" name:"overwrite" brief:"overwrite service go files that already exist in generating folder. default: true" d:"true" orphan:"true"`
|
||||
|
||||
79
contrib/registry/etcd/README.MD
Normal file
79
contrib/registry/etcd/README.MD
Normal file
@ -0,0 +1,79 @@
|
||||
# GoFrame Etcd Registry
|
||||
|
||||
|
||||
Use `etcd` as service registration and discovery management.
|
||||
|
||||
|
||||
## Installation
|
||||
```
|
||||
go get -u -v github.com/gogf/gf/contrib/registry/etcd/v2
|
||||
```
|
||||
suggested using `go.mod`:
|
||||
```
|
||||
require github.com/gogf/gf/contrib/registry/etcd/v2 latest
|
||||
```
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
### Reference example
|
||||
|
||||
[server](example/registry/etcd/server/main.go)
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/contrib/registry/etcd/v2"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/gsvc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`))
|
||||
|
||||
s := g.Server(`hello.svc`)
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
g.Log().Info(r.Context(), `request received`)
|
||||
r.Response.Write(`Hello world`)
|
||||
})
|
||||
s.Run()
|
||||
}
|
||||
```
|
||||
|
||||
[client](example/registry/etcd/client/main.go)
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/contrib/registry/etcd/v2"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/gsel"
|
||||
"github.com/gogf/gf/v2/net/gsvc"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`))
|
||||
gsel.SetBuilder(gsel.NewBuilderRoundRobin())
|
||||
|
||||
client := g.Client()
|
||||
for i := 0; i < 100; i++ {
|
||||
res, err := client.Get(gctx.New(), `http://hello.svc/`)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(res.ReadAllString())
|
||||
res.Close()
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
`GoFrame etcd` is licensed under the [MIT License](../../../LICENSE), 100% free and open-source, forever.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
English | [简体中文](README_ZH.MD)
|
||||
|
||||
Use Polaris mesh as service registration, discovery management and heartbeat reporting
|
||||
Use `PolarisMesh` as service registration, discovery management and heartbeat reporting.
|
||||
|
||||
|
||||
## Installation
|
||||
@ -14,11 +14,6 @@ suggested using `go.mod`:
|
||||
require github.com/gogf/gf/contrib/registry/polaris/v2 latest
|
||||
```
|
||||
|
||||
## Limitation
|
||||
```
|
||||
golang version >= 1.15
|
||||
```
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
@ -50,7 +45,6 @@ func main() {
|
||||
})
|
||||
s.Run()
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
[client](example/registry/polaris/client/main.go)
|
||||
@ -85,7 +79,6 @@ func main() {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.MD) | 简体中文
|
||||
|
||||
使用Polarismesh作为服务注册、发现管理和心跳上报
|
||||
使用`PolarisMesh`作为服务注册、发现管理和心跳上报。
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
@ -222,6 +222,9 @@ func Code(err error) gcode.Code {
|
||||
if e, ok := err.(iNext); ok {
|
||||
return Code(e.Next())
|
||||
}
|
||||
if e, ok := err.(iUnwrap); ok {
|
||||
return Code(e.Unwrap())
|
||||
}
|
||||
return gcode.CodeNil
|
||||
}
|
||||
|
||||
@ -236,6 +239,9 @@ func Cause(err error) error {
|
||||
if e, ok := err.(iNext); ok {
|
||||
return Cause(e.Next())
|
||||
}
|
||||
if e, ok := err.(iUnwrap); ok {
|
||||
return Cause(e.Unwrap())
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -49,3 +49,9 @@ type iNext interface {
|
||||
Error() string
|
||||
Next() error
|
||||
}
|
||||
|
||||
// iUnwrap is the interface for Unwrap feature.
|
||||
type iUnwrap interface {
|
||||
Error() string
|
||||
Unwrap() error
|
||||
}
|
||||
|
||||
@ -55,3 +55,30 @@ func ExampleWrapCodef() {
|
||||
// It's Custom Error: permission denied
|
||||
// 10000
|
||||
}
|
||||
|
||||
func ExampleEqual() {
|
||||
err1 := errors.New("permission denied")
|
||||
err2 := gerror.New("permission denied")
|
||||
err3 := gerror.NewCode(gcode.CodeNotAuthorized, "permission denied")
|
||||
fmt.Println(gerror.Equal(err1, err2))
|
||||
fmt.Println(gerror.Equal(err2, err3))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleIs() {
|
||||
err1 := errors.New("permission denied")
|
||||
err2 := gerror.Wrap(err1, "operation failed")
|
||||
fmt.Println(gerror.Is(err1, err1))
|
||||
fmt.Println(gerror.Is(err2, err2))
|
||||
fmt.Println(gerror.Is(err2, err1))
|
||||
fmt.Println(gerror.Is(err1, err2))
|
||||
|
||||
// Output:
|
||||
// false
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
@ -79,13 +79,17 @@ func New() *Client {
|
||||
func (c *Client) Clone() *Client {
|
||||
newClient := New()
|
||||
*newClient = *c
|
||||
newClient.header = make(map[string]string)
|
||||
newClient.cookies = make(map[string]string)
|
||||
for k, v := range c.header {
|
||||
newClient.header[k] = v
|
||||
if len(c.header) > 0 {
|
||||
newClient.header = make(map[string]string)
|
||||
for k, v := range c.header {
|
||||
newClient.header[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range c.cookies {
|
||||
newClient.cookies[k] = v
|
||||
if len(c.cookies) > 0 {
|
||||
newClient.cookies = make(map[string]string)
|
||||
for k, v := range c.cookies {
|
||||
newClient.cookies[k] = v
|
||||
}
|
||||
}
|
||||
return newClient
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ import (
|
||||
|
||||
// Prefix is a chaining function,
|
||||
// which sets the URL prefix for next request of this client.
|
||||
// Eg:
|
||||
// Prefix("http://127.0.0.1:8199/api/v1")
|
||||
// Prefix("http://127.0.0.1:8199/api/v2")
|
||||
func (c *Client) Prefix(prefix string) *Client {
|
||||
newClient := c.Clone()
|
||||
newClient.SetPrefix(prefix)
|
||||
|
||||
95
net/gclient/gclient_request_obj.go
Normal file
95
net/gclient/gclient_request_obj.go
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gmeta"
|
||||
)
|
||||
|
||||
// DoRequestObj does HTTP request using standard request/response object.
|
||||
// The request object `req` is defined like:
|
||||
// type UseCreateReq struct {
|
||||
// g.Meta `path:"/user" method:"put"`
|
||||
// // other fields....
|
||||
// }
|
||||
// The response object `res` should be a pointer type. It automatically converts result
|
||||
// to given object `res` is success.
|
||||
// Eg:
|
||||
// var (
|
||||
// req = UseCreateReq{}
|
||||
// res *UseCreateRes
|
||||
// )
|
||||
// DoRequestObj(ctx, req, &res)
|
||||
func (c *Client) DoRequestObj(ctx context.Context, req, res interface{}) error {
|
||||
var (
|
||||
method = gmeta.Get(req, goai.TagNameMethod).String()
|
||||
path = gmeta.Get(req, goai.TagNamePath).String()
|
||||
)
|
||||
if method == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`no "%s" tag found in request object: %s`,
|
||||
goai.TagNameMethod, reflect.TypeOf(req).String(),
|
||||
)
|
||||
}
|
||||
if path == "" {
|
||||
return gerror.NewCodef(
|
||||
gcode.CodeInvalidParameter,
|
||||
`no "%s" tag found in request object: %s`,
|
||||
goai.TagNamePath, reflect.TypeOf(req).String(),
|
||||
)
|
||||
}
|
||||
path = c.handlePathForObjRequest(path, req)
|
||||
switch gstr.ToUpper(method) {
|
||||
case
|
||||
http.MethodGet,
|
||||
http.MethodPut,
|
||||
http.MethodPost,
|
||||
http.MethodDelete,
|
||||
http.MethodHead,
|
||||
http.MethodPatch,
|
||||
http.MethodConnect,
|
||||
http.MethodOptions,
|
||||
http.MethodTrace:
|
||||
if result := c.RequestVar(ctx, method, path, req); res != nil && !result.IsEmpty() {
|
||||
return result.Scan(res)
|
||||
}
|
||||
return nil
|
||||
|
||||
default:
|
||||
return gerror.Newf(`invalid HTTP method "%s"`, method)
|
||||
}
|
||||
}
|
||||
|
||||
// handlePathForObjRequest replaces parameters in `path` with parameters from request object.
|
||||
// Eg:
|
||||
// /order/{id} -> /order/1
|
||||
// /user/{name} -> /order/john
|
||||
func (c *Client) handlePathForObjRequest(path string, req interface{}) string {
|
||||
if gstr.Contains(path, "{") {
|
||||
requestParamsMap := gconv.MapStrStr(req)
|
||||
if len(requestParamsMap) > 0 {
|
||||
path, _ = gregex.ReplaceStringFuncMatch(`\{(\w+)\}`, path, func(match []string) string {
|
||||
if v, ok := requestParamsMap[match[1]]; ok {
|
||||
return v
|
||||
}
|
||||
return match[1]
|
||||
})
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
@ -11,13 +11,14 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
|
||||
78
net/gclient/gclient_z_unit_feature_trace_test.go
Normal file
78
net/gclient/gclient_z_unit_feature_trace_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gclient_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/internal/tracing"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"go.opentelemetry.io/otel"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type CustomProvider struct {
|
||||
*sdkTrace.TracerProvider
|
||||
}
|
||||
|
||||
func NewCustomProvider() *CustomProvider {
|
||||
return &CustomProvider{
|
||||
TracerProvider: sdkTrace.NewTracerProvider(
|
||||
sdkTrace.WithIDGenerator(NewCustomIDGenerator()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type CustomIDGenerator struct{}
|
||||
|
||||
func NewCustomIDGenerator() *CustomIDGenerator {
|
||||
return &CustomIDGenerator{}
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewIDs(ctx context.Context) (traceID trace.TraceID, spanID trace.SpanID) {
|
||||
return tracing.NewIDs()
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) (spanID trace.SpanID) {
|
||||
return tracing.NewSpanID()
|
||||
}
|
||||
|
||||
func TestClient_CustomProvider(t *testing.T) {
|
||||
provider := otel.GetTracerProvider()
|
||||
defer otel.SetTracerProvider(provider)
|
||||
|
||||
otel.SetTracerProvider(NewCustomProvider())
|
||||
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.BindHandler("/hello", func(r *ghttp.Request) {
|
||||
r.Response.WriteHeader(200)
|
||||
r.Response.WriteJson(g.Map{"field": "test_for_response_body"})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
c := g.Client()
|
||||
url := fmt.Sprintf("127.0.0.1:%d/hello", p)
|
||||
resp, err := c.DoRequest(ctx, http.MethodGet, url)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(resp, nil)
|
||||
t.Assert(resp.ReadAllString(), "{\"field\":\"test_for_response_body\"}")
|
||||
})
|
||||
}
|
||||
78
net/gclient/gclient_z_unit_request_obj_test.go
Normal file
78
net/gclient/gclient_z_unit_request_obj_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gclient_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Client_DoRequestObj(t *testing.T) {
|
||||
type UserCreateReq struct {
|
||||
g.Meta `path:"/user" method:"post"`
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
type UserCreateRes struct {
|
||||
Id int
|
||||
}
|
||||
type UserQueryReq struct {
|
||||
g.Meta `path:"/user" method:"get"`
|
||||
}
|
||||
type UserQueryRes struct {
|
||||
Id int
|
||||
Name string
|
||||
}
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.Group("/user", func(group *ghttp.RouterGroup) {
|
||||
group.GET("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteJson(g.Map{"id": 1, "name": "john"})
|
||||
})
|
||||
group.POST("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteJson(g.Map{"id": r.Get("Id")})
|
||||
})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
client := g.Client().SetPrefix(url).ContentJson()
|
||||
var (
|
||||
createRes *UserCreateRes
|
||||
createReq = UserCreateReq{
|
||||
Id: 1,
|
||||
Name: "john",
|
||||
}
|
||||
)
|
||||
err := client.DoRequestObj(ctx, createReq, &createRes)
|
||||
t.AssertNil(err)
|
||||
t.Assert(createRes.Id, 1)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
url := fmt.Sprintf("http://127.0.0.1:%d", p)
|
||||
client := g.Client().SetPrefix(url).ContentJson()
|
||||
var (
|
||||
queryRes *UserQueryRes
|
||||
queryReq = UserQueryReq{}
|
||||
)
|
||||
err := client.DoRequestObj(ctx, queryReq, &queryRes)
|
||||
t.AssertNil(err)
|
||||
t.Assert(queryRes.Id, 1)
|
||||
t.Assert(queryRes.Name, "john")
|
||||
})
|
||||
}
|
||||
@ -11,16 +11,13 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
"github.com/gogf/gf/v2/internal/tracing"
|
||||
"go.opentelemetry.io/otel"
|
||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/debug/gdebug"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
@ -643,58 +640,3 @@ func TestClient_RequestVar(t *testing.T) {
|
||||
t.AssertNE(users, nil)
|
||||
})
|
||||
}
|
||||
|
||||
type CustomProvider struct {
|
||||
*sdkTrace.TracerProvider
|
||||
}
|
||||
|
||||
func NewCustomProvider() *CustomProvider {
|
||||
return &CustomProvider{
|
||||
TracerProvider: sdkTrace.NewTracerProvider(
|
||||
sdkTrace.WithIDGenerator(NewCustomIDGenerator()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type CustomIDGenerator struct{}
|
||||
|
||||
func NewCustomIDGenerator() *CustomIDGenerator {
|
||||
return &CustomIDGenerator{}
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewIDs(ctx context.Context) (traceID trace.TraceID, spanID trace.SpanID) {
|
||||
return tracing.NewIDs()
|
||||
}
|
||||
|
||||
func (id *CustomIDGenerator) NewSpanID(ctx context.Context, traceID trace.TraceID) (spanID trace.SpanID) {
|
||||
return tracing.NewSpanID()
|
||||
}
|
||||
|
||||
func TestClient_CustomProvider(t *testing.T) {
|
||||
provider := otel.GetTracerProvider()
|
||||
defer otel.SetTracerProvider(provider)
|
||||
|
||||
otel.SetTracerProvider(NewCustomProvider())
|
||||
|
||||
p, _ := gtcp.GetFreePort()
|
||||
s := g.Server(p)
|
||||
s.BindHandler("/hello", func(r *ghttp.Request) {
|
||||
r.Response.WriteHeader(200)
|
||||
r.Response.WriteJson(g.Map{"field": "test_for_response_body"})
|
||||
})
|
||||
s.SetPort(p)
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
c := g.Client()
|
||||
url := fmt.Sprintf("127.0.0.1:%d/hello", p)
|
||||
resp, err := c.DoRequest(ctx, http.MethodGet, url)
|
||||
t.AssertNil(err)
|
||||
t.AssertNE(resp, nil)
|
||||
t.Assert(resp.ReadAllString(), "{\"field\":\"test_for_response_body\"}")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
)
|
||||
|
||||
// DefaultHandlerResponse is the default implementation of HandlerResponse.
|
||||
@ -32,7 +31,6 @@ func MiddlewareHandlerResponse(r *Request) {
|
||||
|
||||
var (
|
||||
msg string
|
||||
ctx = r.Context()
|
||||
err = r.GetError()
|
||||
res = r.GetHandlerResponse()
|
||||
code = gerror.Code(err)
|
||||
@ -55,12 +53,9 @@ func MiddlewareHandlerResponse(r *Request) {
|
||||
} else {
|
||||
code = gcode.CodeOK
|
||||
}
|
||||
internalErr := r.Response.WriteJson(DefaultHandlerResponse{
|
||||
r.Response.WriteJson(DefaultHandlerResponse{
|
||||
Code: code.Code(),
|
||||
Message: msg,
|
||||
Data: res,
|
||||
})
|
||||
if internalErr != nil {
|
||||
intlog.Errorf(ctx, `%+v`, internalErr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@ -102,48 +103,42 @@ func (r *Response) WriteflnExit(format string, params ...interface{}) {
|
||||
}
|
||||
|
||||
// WriteJson writes `content` to the response with JSON format.
|
||||
func (r *Response) WriteJson(content interface{}) error {
|
||||
func (r *Response) WriteJson(content interface{}) {
|
||||
r.Header().Set("Content-Type", contentTypeJson)
|
||||
// If given string/[]byte, response it directly to the client.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
// Else use json.Marshal function to encode the parameter.
|
||||
if b, err := json.Marshal(content); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteJson failed`))
|
||||
} else {
|
||||
r.Write(b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonExit writes `content` to the response with JSON format and exits executing
|
||||
// of current handler if success. The "Exit" feature is commonly used to replace usage of
|
||||
// return statements in the handler, for convenience.
|
||||
func (r *Response) WriteJsonExit(content interface{}) error {
|
||||
if err := r.WriteJson(content); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteJsonExit(content interface{}) {
|
||||
r.WriteJson(content)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonP writes `content` to the response with JSONP format.
|
||||
//
|
||||
// Note that there should be a "callback" parameter in the request for JSONP format.
|
||||
func (r *Response) WriteJsonP(content interface{}) error {
|
||||
func (r *Response) WriteJsonP(content interface{}) {
|
||||
r.Header().Set("Content-Type", contentTypeJson)
|
||||
// If given string/[]byte, response it directly to client.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
// Else use json.Marshal function to encode the parameter.
|
||||
if b, err := json.Marshal(content); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteJsonP failed`))
|
||||
} else {
|
||||
// r.Header().Set("Content-Type", "application/json")
|
||||
if callback := r.Request.Get("callback").String(); callback != "" {
|
||||
@ -156,7 +151,6 @@ func (r *Response) WriteJsonP(content interface{}) error {
|
||||
r.Write(b)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteJsonPExit writes `content` to the response with JSONP format and exits executing
|
||||
@ -164,40 +158,32 @@ func (r *Response) WriteJsonP(content interface{}) error {
|
||||
// return statements in the handler, for convenience.
|
||||
//
|
||||
// Note that there should be a "callback" parameter in the request for JSONP format.
|
||||
func (r *Response) WriteJsonPExit(content interface{}) error {
|
||||
if err := r.WriteJsonP(content); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteJsonPExit(content interface{}) {
|
||||
r.WriteJsonP(content)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteXml writes `content` to the response with XML format.
|
||||
func (r *Response) WriteXml(content interface{}, rootTag ...string) error {
|
||||
func (r *Response) WriteXml(content interface{}, rootTag ...string) {
|
||||
r.Header().Set("Content-Type", contentTypeXml)
|
||||
// If given string/[]byte, response it directly to clients.
|
||||
switch content.(type) {
|
||||
case string, []byte:
|
||||
r.Write(gconv.String(content))
|
||||
return nil
|
||||
}
|
||||
if b, err := gjson.New(content).ToXml(rootTag...); err != nil {
|
||||
return err
|
||||
panic(gerror.Wrap(err, `WriteXml failed`))
|
||||
} else {
|
||||
r.Write(b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteXmlExit writes `content` to the response with XML format and exits executing
|
||||
// of current handler if success. The "Exit" feature is commonly used to replace usage
|
||||
// of return statements in the handler, for convenience.
|
||||
func (r *Response) WriteXmlExit(content interface{}, rootTag ...string) error {
|
||||
if err := r.WriteXml(content, rootTag...); err != nil {
|
||||
return err
|
||||
}
|
||||
func (r *Response) WriteXmlExit(content interface{}, rootTag ...string) {
|
||||
r.WriteXml(content, rootTag...)
|
||||
r.Request.Exit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteStatus writes HTTP `status` and `content` to the response.
|
||||
|
||||
@ -9,7 +9,6 @@ package ghttp
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/intlog"
|
||||
"github.com/gogf/gf/v2/net/goai"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
@ -48,16 +47,9 @@ func (s *Server) initOpenApi() {
|
||||
|
||||
// openapiSpec is a build-in handler automatic producing for openapi specification json file.
|
||||
func (s *Server) openapiSpec(r *Request) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
if s.config.OpenApiPath == "" {
|
||||
r.Response.Write(`OpenApi specification file producing is disabled`)
|
||||
} else {
|
||||
err = r.Response.WriteJson(s.openapi)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
intlog.Errorf(r.Context(), `%+v`, err)
|
||||
r.Response.WriteJson(s.openapi)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user