-
Notifications
You must be signed in to change notification settings - Fork 4
/
param.go
79 lines (62 loc) · 1.62 KB
/
param.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package param
import (
"encoding/json"
"net/http"
"github.com/asaskevich/govalidator"
"github.com/go-chi/chi"
"github.com/spf13/cast"
"github.com/twitchtv/twirp"
)
// String read param in path or query
func String(r *http.Request, key string) string {
v := chi.URLParam(r, key)
if v == "" {
v = r.URL.Query().Get(key)
}
return v
}
func Int(r *http.Request, key string) int {
return cast.ToInt(String(r, key))
}
func Int64(r *http.Request, key string) int64 {
return cast.ToInt64(String(r, key))
}
func Bool(r *http.Request, key string) bool {
return cast.ToBool(String(r, key))
}
// Binding decode request params to struct with json tag
func Binding(r *http.Request, v interface{}) error {
var err error
switch r.Method {
case http.MethodPatch, http.MethodPost, http.MethodPut:
err = bindingBody(r, v)
default:
err = bindingParams(r, v)
}
if err == nil {
if _, verr := govalidator.ValidateStruct(v); verr != nil {
err = twirp.NewError(twirp.InvalidArgument, verr.Error())
}
}
return err
}
func bindingBody(r *http.Request, v interface{}) error {
if err := json.NewDecoder(r.Body).Decode(v); err != nil {
return twirp.NewError(twirp.Malformed, "can't decode request body")
}
return nil
}
func bindingParams(r *http.Request, v interface{}) error {
values := r.URL.Query()
if ctx := chi.RouteContext(r.Context()); ctx != nil {
params := ctx.URLParams
for idx := range params.Keys {
key, value := params.Keys[idx], params.Values[idx]
values.Set(key, value)
}
}
if err := globalDecoder.Decode(v, values); err != nil {
return twirp.NewError(twirp.InvalidArgument, err.Error())
}
return nil
}