-
Notifications
You must be signed in to change notification settings - Fork 4
/
crud.go
110 lines (95 loc) · 3.06 KB
/
crud.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
package goal
import (
"fmt"
"net/http"
)
// HTTP Methods
const (
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
HEAD = "HEAD"
PATCH = "PATCH"
)
// GetSupporter is the interface that provides the Get
// method a resource must support to receive HTTP GETs.
type GetSupporter interface {
Get(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// PostSupporter is the interface that provides the Post
// method a resource must support to receive HTTP POSTs.
type PostSupporter interface {
Post(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// PutSupporter is the interface that provides the Put
// method a resource must support to receive HTTP PUTs.
type PutSupporter interface {
Put(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// DeleteSupporter is the interface that provides the Delete
// method a resource must support to receive HTTP DELETEs.
type DeleteSupporter interface {
Delete(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// HeadSupporter is the interface that provides the Head
// method a resource must support to receive HTTP HEADs.
type HeadSupporter interface {
Head(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// PatchSupporter is the interface that provides the Patch
// method a resource must support to receive HTTP PATCHs.
type PatchSupporter interface {
Patch(http.ResponseWriter, *http.Request) (int, interface{}, error)
}
// Route request to correct handler and write result back to client
func (api *API) crudHandler(resource interface{}) http.HandlerFunc {
return func(rw http.ResponseWriter, request *http.Request) {
var handler simpleResponse
switch request.Method {
case GET:
if resource, ok := resource.(GetSupporter); ok {
handler = resource.Get
}
case POST:
if resource, ok := resource.(PostSupporter); ok {
handler = resource.Post
}
case PUT:
if resource, ok := resource.(PutSupporter); ok {
handler = resource.Put
}
case DELETE:
if resource, ok := resource.(DeleteSupporter); ok {
handler = resource.Delete
}
case HEAD:
if resource, ok := resource.(HeadSupporter); ok {
handler = resource.Head
}
case PATCH:
if resource, ok := resource.(PatchSupporter); ok {
handler = resource.Patch
}
}
renderJSON(rw, request, handler)
}
}
// AddCrudResource adds a new resource to an API. The API will route
// requests that match one of the given paths to the matching HTTP
// method on the resource.
func (api *API) AddCrudResource(resource interface{}, paths ...string) {
for _, path := range paths {
api.Mux().HandleFunc(path, api.crudHandler(resource))
}
}
// AddDefaultCrudPaths adds default path for a resource.
// The default path is based on the struct name
func (api *API) AddDefaultCrudPaths(resource interface{}) {
// Extract name of resource type
name := TableName(resource)
// Default path to interact with resource
createPath := fmt.Sprintf("/%s", name)
detailPath := fmt.Sprintf("/%s/{id:[a-zA-Z0-9]+}", name)
api.AddCrudResource(resource, createPath, detailPath)
}