-
Notifications
You must be signed in to change notification settings - Fork 0
/
procedure.go
45 lines (39 loc) · 1.08 KB
/
procedure.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
package ferry
import (
"context"
"net/http"
)
// Procedure will return Handler which can be used to register remote procedure in Router.
// This function call will panic if procedure function does not have receiver or Request structure is unparsable.
func Procedure[Req any, Res any](fn func(ctx context.Context, r *Req) (*Res, error)) Handler {
mt, err := buildMeta(fn, new(Req))
if err != nil {
panic(err)
}
decodeFn := decodeJSON[Req]
if len(mt.body) == 0 {
// skip decoding if there are no parameters.
decodeFn = func(r *http.Request, v *Req) error { return nil }
}
return &procedureHandler{
meta: mt,
builder: func(m *mux) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var requestValue Req
if err := decodeFn(r, &requestValue); err != nil {
m.errHandler(w, r, err)
return
}
response, err := fn(createContext(w, r), &requestValue)
if err != nil {
m.errHandler(w, r, err)
return
}
if err := Encode(w, r, http.StatusOK, response); err != nil {
m.errHandler(w, r, err)
return
}
}
},
}
}