Skip to content

Commit

Permalink
add DoRequestObj function for gclient.Client
Browse files Browse the repository at this point in the history
  • Loading branch information
gqcn committed Jun 15, 2022
1 parent 481c50f commit babc69e
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 6 deletions.
16 changes: 10 additions & 6 deletions net/gclient/gclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
3 changes: 3 additions & 0 deletions net/gclient/gclient_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
95 changes: 95 additions & 0 deletions net/gclient/gclient_request_obj.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit babc69e

Please sign in to comment.