-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathresource.go
70 lines (59 loc) · 1.83 KB
/
resource.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
package lion
import (
"net/http"
"reflect"
"strings"
)
// Resource defines the minimum required methods
type Resource interface{}
// resourceUses is an interface with the Uses() method which can be used to define global middlewares for the resource.
type resourceUses interface {
Uses() Middlewares
}
// Resource registers a Resource with the corresponding pattern
func (r *Router) Resource(pattern string, resource Resource) {
sub := r.Group(pattern)
if usesRes, ok := resource.(resourceUses); ok {
if len(usesRes.Uses()) > 0 {
sub.Use(usesRes.Uses()...)
}
}
for _, m := range allowedHTTPMethods {
if hfn, ok := isHandlerFuncInResource(m, resource); ok {
s := sub.Subrouter()
if mws, ok := isMiddlewareInResource(m, resource); ok {
s.Use(mws()...)
}
s.HandleFunc(m, "/", http.HandlerFunc(hfn))
}
}
}
// checks if there is a Name(w http.ResponseWriter, r *http.Request) method available on the Resource r
func isHandlerFuncInResource(m string, r Resource) (func(w http.ResponseWriter, r *http.Request), bool) {
name := strings.Title(strings.ToLower(m))
method := reflect.ValueOf(r).MethodByName(name)
if !method.IsValid() {
return nil, false
}
// Native http.HandlerFunc
fn, ok := method.Interface().(func(w http.ResponseWriter, r *http.Request))
if ok {
return fn, true
}
// ... or check for a contextual handler
cfn, ok := method.Interface().(func(Context))
if !ok {
return nil, false
}
return wrap(cfn).ServeHTTP, ok
}
// checks if there is a NameMiddlewares() Middlewares method available on the Resource r
func isMiddlewareInResource(m string, r Resource) (func() Middlewares, bool) {
name := strings.Title(strings.ToLower(m)) + "Middlewares"
method := reflect.ValueOf(r).MethodByName(name)
if !method.IsValid() {
return nil, false
}
fn, ok := method.Interface().(func() Middlewares)
return fn, ok
}