Adaptation of @shore's proposal from #95
Peter Bourgon
8 years ago
18 | 18 |
|
19 | 19 |
// ContextCanceled indicates the request context was canceled.
|
20 | 20 |
var ErrContextCanceled = errors.New("context canceled")
|
|
21 |
|
|
22 |
// Chain is a helper function for composing middlewares. Requests will
|
|
23 |
// traverse them in the order they're declared. That is, the first middleware
|
|
24 |
// is treated as the outermost middleware.
|
|
25 |
func Chain(outer Middleware, others ...Middleware) Middleware {
|
|
26 |
return func(next Endpoint) Endpoint {
|
|
27 |
for i := len(others) - 1; i >= 0; i-- { // reverse
|
|
28 |
next = others[i](next)
|
|
29 |
}
|
|
30 |
return outer(next)
|
|
31 |
}
|
|
32 |
}
|
|
0 |
package endpoint_test
|
|
1 |
|
|
2 |
import (
|
|
3 |
"fmt"
|
|
4 |
|
|
5 |
"golang.org/x/net/context"
|
|
6 |
|
|
7 |
"github.com/go-kit/kit/endpoint"
|
|
8 |
)
|
|
9 |
|
|
10 |
func ExampleChain() {
|
|
11 |
e := endpoint.Chain(
|
|
12 |
annotate("first"),
|
|
13 |
annotate("second"),
|
|
14 |
annotate("third"),
|
|
15 |
)(myEndpoint)
|
|
16 |
|
|
17 |
if _, err := e(ctx, req); err != nil {
|
|
18 |
panic(err)
|
|
19 |
}
|
|
20 |
|
|
21 |
// Output:
|
|
22 |
// first pre
|
|
23 |
// second pre
|
|
24 |
// third pre
|
|
25 |
// my endpoint!
|
|
26 |
// third post
|
|
27 |
// second post
|
|
28 |
// first post
|
|
29 |
}
|
|
30 |
|
|
31 |
var (
|
|
32 |
ctx = context.Background()
|
|
33 |
req = struct{}{}
|
|
34 |
)
|
|
35 |
|
|
36 |
func annotate(s string) endpoint.Middleware {
|
|
37 |
return func(next endpoint.Endpoint) endpoint.Endpoint {
|
|
38 |
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
|
39 |
fmt.Println(s, "pre")
|
|
40 |
defer fmt.Println(s, "post")
|
|
41 |
return next(ctx, request)
|
|
42 |
}
|
|
43 |
}
|
|
44 |
}
|
|
45 |
|
|
46 |
func myEndpoint(context.Context, interface{}) (interface{}, error) {
|
|
47 |
fmt.Println("my endpoint!")
|
|
48 |
return struct{}{}, nil
|
|
49 |
}
|