Skip to content

Commit cb2eafd

Browse files
committed
feat: add support to regexp path for gorilla router
1 parent b04fd26 commit cb2eafd

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

support/gorilla/gorilla.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package gorilla
22

33
import (
4+
"regexp"
5+
46
"github.com/davidebianchi/gswagger/apirouter"
57

68
"net/http"
@@ -29,7 +31,8 @@ func (r gorillaRouter) SwaggerHandler(contentType string, blob []byte) HandlerFu
2931
}
3032

3133
func (r gorillaRouter) TransformPathToOasPath(path string) string {
32-
return path
34+
re := regexp.MustCompile(`\{([^:}]+):[^}]*\}`)
35+
return re.ReplaceAllString(path, "{$1}")
3336
}
3437

3538
func NewRouter(router *mux.Router) apirouter.Router[HandlerFunc, Route] {

support/gorilla/gorilla_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,87 @@ func TestGorillaMuxRouter(t *testing.T) {
6464
})
6565
})
6666
}
67+
68+
func TestTransformPath(t *testing.T) {
69+
testCases := []struct {
70+
name string
71+
path string
72+
expectedPath string
73+
}{
74+
{
75+
name: "only /",
76+
path: "/",
77+
expectedPath: "/",
78+
},
79+
{
80+
name: "without params",
81+
path: "/foo",
82+
expectedPath: "/foo",
83+
},
84+
{
85+
name: "without params ending with /",
86+
path: "/foo/",
87+
expectedPath: "/foo/",
88+
},
89+
{
90+
name: "with params",
91+
path: "/foo/{par1}",
92+
expectedPath: "/foo/{par1}",
93+
},
94+
{
95+
name: "with params ending with /",
96+
path: "/foo/{par1}/",
97+
expectedPath: "/foo/{par1}/",
98+
},
99+
{
100+
name: "with multiple params",
101+
path: "/{par1}/{par2}/{par3}",
102+
expectedPath: "/{par1}/{par2}/{par3}",
103+
},
104+
{
105+
name: "with multiple params ending with /",
106+
path: "/{par1}/{par2}/{par3}/",
107+
expectedPath: "/{par1}/{par2}/{par3}/",
108+
},
109+
{
110+
name: "with multiple params in a segment",
111+
path: "/foo/{par2}{par3}",
112+
expectedPath: "/foo/{par2}{par3}",
113+
},
114+
{
115+
name: "with multiple params in a segment ending with /",
116+
path: "/foo/{par2}{par3}/",
117+
expectedPath: "/foo/{par2}{par3}/",
118+
},
119+
{
120+
name: "with regex",
121+
path: "/foo/{par1:[0-9]}/{par2:[a-z]}",
122+
expectedPath: "/foo/{par1}/{par2}",
123+
},
124+
{
125+
name: "with regex ending with /",
126+
path: "/foo/{par1:[0-9]}/{par2:[a-z]}/",
127+
expectedPath: "/foo/{par1}/{par2}/",
128+
},
129+
{
130+
name: "with multiple params in a segment and the regex",
131+
path: "/foo/{par2:[0-9]}{par3:a|b}/",
132+
expectedPath: "/foo/{par2}{par3}/",
133+
},
134+
{
135+
name: "with multiple params in a segment and the regex ending with /",
136+
path: "/foo/{par2:[0-9]}{par3:\\w+}/",
137+
expectedPath: "/foo/{par2}{par3}/",
138+
},
139+
}
140+
141+
router := NewRouter(mux.NewRouter())
142+
143+
for _, test := range testCases {
144+
145+
t.Run(test.name, func(t *testing.T) {
146+
actual := router.TransformPathToOasPath(test.path)
147+
require.Equal(t, test.expectedPath, actual)
148+
})
149+
}
150+
}

support/gorilla/integration_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ func TestGorillaIntegration(t *testing.T) {
3939
body := readBody(t, w.Result().Body)
4040
require.Equal(t, "OK", body)
4141

42+
t.Run("api with regex", func(t *testing.T) {
43+
t.Run("router exposes correctly api", func(t *testing.T) {
44+
w := httptest.NewRecorder()
45+
r := httptest.NewRequest(http.MethodGet, "/foo/8", nil)
46+
47+
muxRouter.ServeHTTP(w, r)
48+
49+
require.Equal(t, http.StatusOK, w.Result().StatusCode)
50+
})
51+
52+
t.Run("router exposes correctly api", func(t *testing.T) {
53+
w := httptest.NewRecorder()
54+
r := httptest.NewRequest(http.MethodGet, "/foo/10", nil)
55+
56+
muxRouter.ServeHTTP(w, r)
57+
58+
require.Equal(t, http.StatusBadRequest, w.Result().StatusCode)
59+
})
60+
})
61+
4262
t.Run("and generate swagger", func(t *testing.T) {
4363
w := httptest.NewRecorder()
4464
r := httptest.NewRequest(http.MethodGet, swagger.DefaultJSONDocumentationPath, nil)
@@ -139,6 +159,9 @@ func setupSwagger(t *testing.T) (*mux.Router, *SwaggerRouter) {
139159
_, err = router.AddRoute(http.MethodPost, "/hello/{value}", okHandler, swagger.Definitions{})
140160
require.NoError(t, err)
141161

162+
_, err = router.AddRoute(http.MethodGet, "/foo/{id:0-9}", okHandler, swagger.Definitions{})
163+
require.NoError(t, err)
164+
142165
return muxRouter, router
143166
}
144167

support/testdata/integration.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@
55
},
66
"openapi": "3.0.0",
77
"paths": {
8+
"/foo/{id}": {
9+
"get": {
10+
"parameters": [
11+
{
12+
"in": "path",
13+
"name": "id",
14+
"required": true,
15+
"schema": {
16+
"type": "string"
17+
}
18+
}
19+
],
20+
"responses": {
21+
"default": {
22+
"description": ""
23+
}
24+
}
25+
}
26+
},
827
"/hello": {
928
"get": {
1029
"responses": {

support/testdata/intergation-subrouter.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@
55
},
66
"openapi": "3.0.0",
77
"paths": {
8+
"/foo/{id}": {
9+
"get": {
10+
"parameters": [
11+
{
12+
"in": "path",
13+
"name": "id",
14+
"required": true,
15+
"schema": {
16+
"type": "string"
17+
}
18+
}
19+
],
20+
"responses": {
21+
"default": {
22+
"description": ""
23+
}
24+
}
25+
}
26+
},
827
"/hello": {
928
"get": {
1029
"responses": {

0 commit comments

Comments
 (0)