-
Notifications
You must be signed in to change notification settings - Fork 6
/
finders.go
104 lines (91 loc) · 3.05 KB
/
finders.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package restli
import (
"context"
"log"
"net/http"
"github.com/PapaCharlie/go-restli/restlicodec"
"github.com/PapaCharlie/go-restli/restlidata"
)
// Find executes a rest.li find request
func Find[V restlicodec.Marshaler](
c *Client,
ctx context.Context,
rp ResourcePath,
query QueryParamsEncoder,
) (results *restlidata.Elements[V], err error) {
req, err := NewGetRequest(c, ctx, rp, query, Method_finder)
if err != nil {
return nil, err
}
results, _, err = DoAndUnmarshal(c, req, restlicodec.UnmarshalRestLi[*restlidata.Elements[V]])
return results, nil
}
// FindWithMetadata executes a rest.li find request for finders that declare metadata
func FindWithMetadata[V, M restlicodec.Marshaler](
c *Client,
ctx context.Context,
rp ResourcePath,
query QueryParamsEncoder,
) (results *restlidata.ElementsWithMetadata[V, M], err error) {
req, err := NewGetRequest(c, ctx, rp, query, Method_finder)
if err != nil {
return nil, err
}
results, _, err = DoAndUnmarshal(c, req, restlicodec.UnmarshalRestLi[*restlidata.ElementsWithMetadata[V, M]])
return results, nil
}
func RegisterFinder[RP ResourcePathUnmarshaler[RP], QP restlicodec.QueryParamsDecoder[QP], V restlicodec.Marshaler](
s Server,
segments []ResourcePathSegment,
name string,
find func(*RequestContext, RP, QP) (*restlidata.Elements[V], error),
) {
registerFinder(s, segments, name,
func(ctx *RequestContext, rp RP, qp QP) (restlicodec.Marshaler, error) {
return find(ctx, rp, qp)
})
}
func RegisterFinderWithMetadata[RP ResourcePathUnmarshaler[RP], QP restlicodec.QueryParamsDecoder[QP], V, M restlicodec.Marshaler](
s Server,
segments []ResourcePathSegment,
name string,
find func(*RequestContext, RP, QP) (*restlidata.ElementsWithMetadata[V, M], error),
) {
registerFinder(s, segments, name,
func(ctx *RequestContext, rp RP, p QP) (restlicodec.Marshaler, error) {
return find(ctx, rp, p)
})
}
func registerFinder[RP ResourcePathUnmarshaler[RP], QP restlicodec.QueryParamsDecoder[QP]](
s Server,
segments []ResourcePathSegment,
name string,
h func(*RequestContext, RP, QP) (restlicodec.Marshaler, error),
) {
p := s.subNode(segments)
if _, ok := p.finders[name]; ok {
log.Panicf("go-restli: Cannot register finder %q twice for %v", name, segments)
}
p.finders[name] = func(
ctx *RequestContext,
segments []restlicodec.Reader,
body []byte,
) (responseBody restlicodec.Marshaler, err error) {
rp, err := UnmarshalResourcePath[RP](segments)
if err != nil {
return newErrorResponsef(err, http.StatusBadRequest, "Invalid path for finder %q: %s", name)
}
queryParams, err := restlicodec.UnmarshalQueryParamsDecoder[QP](ctx.Request.URL.RawQuery)
if err != nil {
return newErrorResponsef(err, http.StatusBadRequest, "Invalid query params for finder %q: %s", name)
}
if len(body) != 0 {
return newErrorResponsef(nil, http.StatusBadRequest, "Finders do not accept request bodies")
}
results, err := h(ctx, rp, queryParams)
if err != nil {
return newErrorResponsef(err, http.StatusInternalServerError, "Finder %q failed: %s", name)
}
return results, nil
}
}