-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathapi.go
108 lines (85 loc) · 2.76 KB
/
api.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
package jshapi
import (
"fmt"
"log"
"os"
"path"
"strings"
"goji.io"
"goji.io/pat"
gojilogger "github.com/derekdowling/go-json-spec-handler/goji2-logger"
"github.com/derekdowling/go-stdlogger"
)
// API is used to direct HTTP requests to resources
type API struct {
*goji.Mux
prefix string
Resources map[string]*Resource
Debug bool
}
/*
SendHandler allows the customization of how API responses are sent and logged. This
is used by all jshapi.Resource objects.
*/
var SendHandler = DefaultSender(log.New(os.Stderr, "jshapi: ", log.LstdFlags))
/*
New initializes a new top level API Resource without doing any additional setup.
*/
func New(prefix string) *API {
// ensure that our top level prefix is "/" prefixed
if !strings.HasPrefix(prefix, "/") {
prefix = fmt.Sprintf("/%s", prefix)
}
// create our new API
return &API{
Mux: goji.NewMux(),
prefix: prefix,
Resources: map[string]*Resource{},
}
}
/*
Default builds a new top-level API with a few out of the box additions to get people
started without needing to add a lot of extra functionality.
The most basic implementation is:
// create a logger, the std log package works, as do most other loggers
// std.Logger interface defined here:
// https://github.com/derekdowling/go-stdlogger/blob/master/logger.go
logger := log.New(os.Stderr, "jshapi: ", log.LstdFlags)
// create the API. Specify a http://yourapi/<prefix>/ if required
api := jshapi.Default("<prefix>", false, logger)
api.Add(yourResource)
*/
func Default(prefix string, debug bool, logger std.Logger) *API {
api := New(prefix)
SendHandler = DefaultSender(logger)
// register logger middleware
gojilogger := gojilogger.New(logger, debug)
api.Use(gojilogger.Middleware)
return api
}
// Add implements mux support for a given resource which is effectively handled as:
// pat.New("/(prefix/)resource.Plu*)
func (a *API) Add(resource *Resource) {
// track our associated resources, will enable auto-generation docs later
a.Resources[resource.Type] = resource
// Because of how prefix matches work:
// https://godoc.org/github.com/goji/goji/pat#hdr-Prefix_Matches
// We need two separate routes,
// /(prefix/)resources
matcher := path.Join(a.prefix, resource.Type)
a.Mux.Handle(pat.New(matcher), resource)
// And:
// /(prefix/)resources/*
idMatcher := path.Join(a.prefix, resource.Type, "*")
a.Mux.Handle(pat.New(idMatcher), resource)
}
// RouteTree prints out all accepted routes for the API that use jshapi implemented
// ways of adding routes through resources: NewCRUDResource(), .Get(), .Post, .Delete(),
// .Patch(), .List(), and .NewAction()
func (a *API) RouteTree() string {
var routes string
for _, resource := range a.Resources {
routes = strings.Join([]string{routes, resource.RouteTree()}, "")
}
return routes
}