This repository has been archived by the owner on May 11, 2019. It is now read-only.
/
helper.go
129 lines (107 loc) · 3.37 KB
/
helper.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
package client
import (
"fmt"
"io"
"net/http"
"net/url"
)
// Call describes an object to be passed into Execute() to define the input and output handling to perform an action on a resource via HTTP.
// To actually trigger behavior, the call struct should implement some of the other interfaces in this package.
type Call interface {
}
// QueryParams can be implemented to provide URL parameters.
type QueryParams interface {
QueryParams() url.Values
}
// PostForm can be implemented to perform a POST with the returned stream.
type PostForm interface {
// Body returns the content-type and stream for the POST body to for this call.
Body() (string, io.Reader)
}
// PostCallForm can be implemented to perform a POST with a classic form-encoded body.
type PostCallForm interface {
PostForm() url.Values
}
// ----------------------------------------
// OKHandler can be implemented to handle the 200 OK case.
type OKHandler interface {
ResponseOK(resp *http.Response) (interface{}, error)
}
type NoContentHandler interface {
ResponseNoContent(resp *http.Response) (interface{}, error)
}
type CreatedHandler interface {
ResponseCreated(resp *http.Response) (interface{}, error)
}
type NotFoundHandler interface {
ResponseNotFound(resp *http.Response) (interface{}, error)
}
type BadRequestHandler interface {
ResponseBadRequest(resp *http.Response) (interface{}, error)
}
type FallbackHandler interface {
// HandleFallback is called when the Call object does not implement the appropriate response handler.
HandleFallback(response *http.Response) (interface{}, error)
}
type RequestErrorHandler interface {
HandleRequestError(err error) (interface{}, error)
}
// -----------------------------------------
func Execute(url string, call Call) (interface{}, error) {
var method string
var response *http.Response
var httpErr error
if c, ok := call.(QueryParams); ok {
url = url + "?" + c.QueryParams().Encode()
}
if c, ok := call.(PostCallForm); ok {
method = "POST"
response, httpErr = http.PostForm(url, c.PostForm())
} else if c, ok := call.(PostForm); ok {
method = "POST"
contentType, body := c.Body()
response, httpErr = http.Post(url, contentType, body)
} else {
method = "GET"
response, httpErr = http.Get(url)
}
// If the call itself failed, call the RequestErrorHandler or just return directly
if httpErr != nil {
if c, ok := call.(RequestErrorHandler); ok {
return c.HandleRequestError(httpErr)
} else {
return nil, httpErr
}
}
defer response.Body.Close()
// Now, call supported handlers
switch response.StatusCode {
case http.StatusOK:
if c, ok := call.(OKHandler); ok {
return c.ResponseOK(response)
}
case http.StatusCreated:
if c, ok := call.(CreatedHandler); ok {
return c.ResponseCreated(response)
}
case http.StatusNoContent:
if c, ok := call.(NoContentHandler); ok {
return c.ResponseNoContent(response)
}
case http.StatusNotFound:
if c, ok := call.(NotFoundHandler); ok {
return c.ResponseNotFound(response)
}
case http.StatusBadRequest:
if c, ok := call.(BadRequestHandler); ok {
return c.ResponseBadRequest(response)
}
default:
}
// Must be outside of switch to catch interface-not-implemented cases
if c, ok := call.(FallbackHandler); ok {
return c.HandleFallback(response)
}
return nil, fmt.Errorf("No handler found for status code %d for URL %s %s", response.StatusCode, method, url)
}
// ------------------