-
Notifications
You must be signed in to change notification settings - Fork 3
/
handler.go
140 lines (116 loc) · 3.19 KB
/
handler.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package fire
import "time"
// A Callback is called during the request processing flow of a controller.
type Callback struct {
// The matcher that decides whether the callback should be run.
Matcher Matcher
// The handler handler that gets executed with the context.
//
// If returned errors are marked with Safe() they will be included in the
// returned JSON-API error.
Handler Handler
}
// L is a short-hand type to create a list of callbacks.
type L = []*Callback
// C is a short-hand function to construct a callback. It will also add tracing
// code around the execution of the callback.
func C(name string, m Matcher, h Handler) *Callback {
// panic if matcher or handler is not set
if m == nil || h == nil {
panic("fire: missing matcher or handler")
}
return &Callback{
Matcher: m,
Handler: func(ctx *Context) error {
// trace
ctx.Trace.Push(name)
defer ctx.Trace.Pop()
// call handler
err := h(ctx)
if err != nil {
return err
}
return nil
},
}
}
// An Action defines a collection or resource action.
type Action struct {
// The allowed methods for this action.
Methods []string
// BodyLimit defines the maximum allowed size of the request body. The
// serve.ByteSize helper can be used to set the value.
//
// Default: 8M.
BodyLimit int64
// Timeout defines the time after which the context is cancelled and
// processing of the action should be stopped.
//
// Default: 30s.
Timeout time.Duration
// The handler handler that gets executed with the context.
//
// If returned errors are marked with Safe() they will be included in the
// returned JSON-API error.
Handler Handler
}
// M is a short-hand type to create a map of actions.
type M = map[string]*Action
// A is a short-hand function to construct an action.
func A(name string, methods []string, bodyLimit int64, h Handler) *Action {
// panic if methods or handler is not set
if len(methods) == 0 || h == nil {
panic("fire: missing methods or handler")
}
return &Action{
Methods: methods,
BodyLimit: bodyLimit,
Handler: func(ctx *Context) error {
// trace
ctx.Trace.Push(name)
defer ctx.Trace.Pop()
// call handler
err := h(ctx)
if err != nil {
return err
}
return nil
},
}
}
// Handler is function that takes a context, mutates is to modify the behaviour
// and response or return an error.
type Handler func(*Context) error
// Matcher is a function that makes an assessment of a context and decides whether
// an operation should be allowed to be carried out.
type Matcher func(*Context) bool
// All will match all contexts.
func All() Matcher {
return func(ctx *Context) bool {
return true
}
}
// Only will match if the operation is present in the provided list.
func Only(ops ...Operation) Matcher {
return func(ctx *Context) bool {
// allow if operation is listed
for _, op := range ops {
if op == ctx.Operation {
return true
}
}
return false
}
}
// Except will match if the operation is not present in the provided list.
func Except(ops ...Operation) Matcher {
return func(ctx *Context) bool {
// disallow if operation is listed
for _, op := range ops {
if op == ctx.Operation {
return false
}
}
return true
}
}