1
1
package goa
2
2
3
3
import (
4
- "encoding/json"
5
- "fmt"
6
4
"net/http"
7
5
"net/url"
8
6
"regexp"
@@ -12,25 +10,11 @@ import (
12
10
)
13
11
14
12
type (
15
- // ServeMux is the interface implemented by the goa HTTP request mux. The goa package
16
- // provides a default implementation with DefaultMux.
17
- //
18
- // The goa mux allows for routing to controllers serving different API versions. Each
19
- // version has is own mux accessed via Version. Upon receving a HTTP request the ServeMux
20
- // ServeHTTP method looks up the targetted API version and dispatches the request to the
21
- // corresponding mux.
22
- ServeMux interface {
23
- VersionMux
24
- // Version returns the mux for the given API version.
25
- Version (version string ) VersionMux
26
- // HandleMissingVersion handles requests that specify a non-existing API version.
27
- HandleMissingVersion (rw http.ResponseWriter , req * http.Request , version string )
28
- }
29
-
30
- // VersionMux is the interface implemented by API version specific request mux.
13
+ // ServeMux is the interface implemented by the service request muxes. There is one instance
14
+ // of ServeMux per service version and one for requests targetting no version.
31
15
// It implements http.Handler and makes it possible to register request handlers for
32
16
// specific HTTP methods and request path via the Handle method.
33
- VersionMux interface {
17
+ ServeMux interface {
34
18
http.Handler
35
19
// Handle sets the HandleFunc for a given HTTP method and path.
36
20
Handle (method , path string , handle HandleFunc )
47
31
// SelectVersion.
48
32
DefaultMux struct {
49
33
* defaultVersionMux
50
- selectVersion SelectVersionFunc
51
- muxes map [string ]VersionMux
34
+ SelectVersionFunc SelectVersionFunc
35
+ missingVerFunc handleMissingVersionFunc
36
+ muxes map [string ]ServeMux
52
37
}
53
38
54
39
// SelectVersionFunc is used by the default goa mux to compute the API version targetted by
@@ -57,26 +42,16 @@ type (
57
42
// Alternate implementations can be set using the DefaultMux SelectVersion method.
58
43
SelectVersionFunc func (* http.Request ) string
59
44
60
- // defaultVersionMux is the default goa API version specific mux.
45
+ // defaultVersionMux is the default API version specific mux implementation .
61
46
defaultVersionMux struct {
62
47
router * httprouter.Router
63
48
handles map [string ]HandleFunc
64
49
}
65
- )
66
50
67
- // NewMux creates a top level mux using the default goa mux implementation.
68
- // The default versioning handling assumes that the base path for the API is "/api" and the
69
- // base paths for each version "/:version/api". Use SelectVersion to specify a different scheme
70
- // if the service exposes a versioned API with different base paths.
71
- func NewMux () ServeMux {
72
- return & DefaultMux {
73
- defaultVersionMux : & defaultVersionMux {
74
- router : httprouter .New (),
75
- handles : make (map [string ]HandleFunc ),
76
- },
77
- selectVersion : PathSelectVersionFunc ("/:version/" , "api" ),
78
- }
79
- }
51
+ // HandleMissingVersionFunc is the signature of the function called back when requests
52
+ // target an unsupported API version.
53
+ handleMissingVersionFunc func (rw http.ResponseWriter , req * http.Request , version string )
54
+ )
80
55
81
56
// PathSelectVersionFunc returns a SelectVersionFunc that uses the given path pattern to extract the
82
57
// version from the request path. Use the same path pattern given in the DSL to define the API base
@@ -124,36 +99,9 @@ func CombineSelectVersionFunc(funcs ...SelectVersionFunc) SelectVersionFunc {
124
99
}
125
100
}
126
101
127
- // Version returns the mux addressing the given version if any.
128
- func (m * DefaultMux ) Version (version string ) VersionMux {
129
- if m .muxes == nil {
130
- m .muxes = make (map [string ]VersionMux )
131
- }
132
- if mux , ok := m .muxes [version ]; ok {
133
- return mux
134
- }
135
- mux := & defaultVersionMux {
136
- router : httprouter .New (),
137
- handles : make (map [string ]HandleFunc ),
138
- }
139
- m .muxes [version ] = mux
140
- return mux
141
- }
142
-
143
102
// SelectVersion sets the func used to compute the API version targetted by a request.
144
103
func (m * DefaultMux ) SelectVersion (sv SelectVersionFunc ) {
145
- m .selectVersion = sv
146
- }
147
-
148
- // HandleMissingVersion handles requests that specify a non-existing API version.
149
- func (m * DefaultMux ) HandleMissingVersion (rw http.ResponseWriter , req * http.Request , version string ) {
150
- rw .WriteHeader (400 )
151
- resp := TypedError {ID : ErrInvalidVersion , Mesg : fmt .Sprintf (`API does not support version %s` , version )}
152
- b , err := json .Marshal (resp )
153
- if err != nil {
154
- b = []byte ("API does not support version" )
155
- }
156
- rw .Write (b )
104
+ m .SelectVersionFunc = sv
157
105
}
158
106
159
107
// ServeHTTP is the function called back by the underlying HTTP server to handle incoming requests.
@@ -163,21 +111,37 @@ func (m *DefaultMux) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
163
111
m .router .ServeHTTP (rw , req )
164
112
return
165
113
}
166
- var mux VersionMux
167
- version := m .selectVersion (req )
114
+ var mux ServeMux
115
+ version := m .SelectVersionFunc (req )
168
116
if version == "" {
169
117
mux = m .defaultVersionMux
170
118
} else {
171
119
var ok bool
172
120
mux , ok = m .muxes [version ]
173
121
if ! ok {
174
- m .HandleMissingVersion (rw , req , version )
122
+ m .missingVerFunc (rw , req , version )
175
123
return
176
124
}
177
125
}
178
126
mux .ServeHTTP (rw , req )
179
127
}
180
128
129
+ // version returns the mux addressing the given version if any.
130
+ func (m * DefaultMux ) version (version string ) ServeMux {
131
+ if m .muxes == nil {
132
+ m .muxes = make (map [string ]ServeMux )
133
+ }
134
+ if mux , ok := m .muxes [version ]; ok {
135
+ return mux
136
+ }
137
+ mux := & defaultVersionMux {
138
+ router : httprouter .New (),
139
+ handles : make (map [string ]HandleFunc ),
140
+ }
141
+ m .muxes [version ] = mux
142
+ return mux
143
+ }
144
+
181
145
// Handle sets the handler for the given verb and path.
182
146
func (m * defaultVersionMux ) Handle (method , path string , handle HandleFunc ) {
183
147
hthandle := func (rw http.ResponseWriter , req * http.Request , htparams httprouter.Params ) {
0 commit comments