api/router/static: allow to specify body dst (#1486)
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
aaee01b1a7
commit
6aaad7d63f
@ -22,7 +22,7 @@ type Api interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type Options struct {}
|
||||
type Options struct{}
|
||||
|
||||
type Option func(*Options) error
|
||||
|
||||
@ -40,6 +40,10 @@ type Endpoint struct {
|
||||
Method []string
|
||||
// HTTP Path e.g /greeter. Expect POSIX regex
|
||||
Path []string
|
||||
// Body destination
|
||||
// "*" or "" - top level message value
|
||||
// "string" - inner message value
|
||||
Body string
|
||||
// Stream flag
|
||||
Stream bool
|
||||
}
|
||||
|
@ -300,6 +300,7 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
||||
|
||||
// allocate maximum
|
||||
matches := make(map[string]interface{}, len(md))
|
||||
bodydst := ""
|
||||
|
||||
// get fields from url path
|
||||
for k, v := range md {
|
||||
@ -307,6 +308,9 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
||||
if strings.HasPrefix(k, "x-api-field-") {
|
||||
matches[strings.TrimPrefix(k, "x-api-field-")] = v
|
||||
delete(md, k)
|
||||
} else if k == "x-api-body" {
|
||||
bodydst = v
|
||||
delete(md, k)
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,10 +391,34 @@ func requestPayload(r *http.Request) ([]byte, error) {
|
||||
} else {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
if bodydst == "" || bodydst == "*" {
|
||||
if out, err = jsonpatch.MergeMergePatches(out, bodybuf); err == nil {
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
dstmap := make(map[string]interface{})
|
||||
ps := strings.Split(bodydst, ".")
|
||||
if len(ps) == 1 {
|
||||
dstmap[ps[0]] = bodybuf
|
||||
} else {
|
||||
em := make(map[string]interface{})
|
||||
em[ps[len(ps)-1]] = bodybuf
|
||||
for i := len(ps) - 2; i > 0; i-- {
|
||||
nm := make(map[string]interface{})
|
||||
nm[ps[i]] = em
|
||||
em = nm
|
||||
}
|
||||
dstmap[ps[0]] = em
|
||||
}
|
||||
|
||||
bodyout, err := json.Marshal(dstmap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if out, err = jsonpatch.MergeMergePatches(out, bodyout); err == nil {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
//fallback to previous unknown behaviour
|
||||
return bodybuf, nil
|
||||
|
@ -191,6 +191,7 @@ func (r *staticRouter) Endpoint(req *http.Request) (*api.Service, error) {
|
||||
Host: ep.apiep.Host,
|
||||
Method: ep.apiep.Method,
|
||||
Path: ep.apiep.Path,
|
||||
Body: ep.apiep.Body,
|
||||
Stream: ep.apiep.Stream,
|
||||
},
|
||||
Services: services,
|
||||
@ -274,6 +275,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
||||
for k, v := range matches {
|
||||
md[fmt.Sprintf("x-api-field-%s", k)] = v
|
||||
}
|
||||
md["x-api-body"] = ep.apiep.Body
|
||||
*req = *req.Clone(context.WithValue(ctx, metadata.MetadataKey{}, md))
|
||||
break pathLoop
|
||||
}
|
||||
@ -285,6 +287,7 @@ func (r *staticRouter) endpoint(req *http.Request) (*endpoint, error) {
|
||||
// we got here, so its a match
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
// no match
|
||||
return nil, fmt.Errorf("endpoint not found for %v", req)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user