mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add DoRequestObj function for gclient.Client
This commit is contained in:
@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user