Skip to content

Commit e7b6938

Browse files
wwwdatasharpner
authored andcommitted
New adapter for the echo framework
1 parent be68f56 commit e7b6938

File tree

12 files changed

+223
-8
lines changed

12 files changed

+223
-8
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ install:
1717
# optional dependencies
1818
- go get -u github.com/gin-gonic/gin
1919
- go get -u github.com/gorilla/mux
20+
- go get -u github.com/labstack/echo/...
2021

2122
script:
2223
- ginkgo -r -cover --randomizeAllSpecs --randomizeSuites --failOnPending --trace --race --progress
2324
- ginkgo -tags=gorillamux -r --randomizeSuites --failOnPending --trace --race
2425
- ginkgo -tags=gingonic -r --randomizeSuites --failOnPending --trace --race
26+
- ginkgo -tags=echo -r --randomizeSuites --failOnPending --trace --race
2527
- rm examples/examples.coverprofile
2628
- bash scripts/fmtpolice
2729
- gover

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ Get the according adapter using:
335335

336336
```go get -tags=gingonic github.com/manyminds/api2go```
337337

338-
Currently the supported tags are: `gingonic` or `gorillamux`.
338+
Currently the supported tags are: `gingonic`,`gorillamux`, or `echo`.
339339

340340
After that you can bootstrap api2go the following way:
341341
```go

echo_router_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// +build echo,!gingonic,!gorillamux
2+
3+
package api2go
4+
5+
import (
6+
"log"
7+
"net/http"
8+
9+
"github.com/labstack/echo"
10+
"github.com/manyminds/api2go/routing"
11+
)
12+
13+
func customHTTPErrorHandler(err error, c echo.Context) {
14+
if he, ok := err.(*echo.HTTPError); ok {
15+
if he == echo.ErrMethodNotAllowed {
16+
handleError(NewHTTPError(he, "Method Not Allowed", http.StatusMethodNotAllowed), c.Response(), c.Request(), defaultContentTypHeader)
17+
}
18+
}
19+
}
20+
21+
func newTestRouter() routing.Routeable {
22+
e := echo.New()
23+
// not found handler, this needs to be fixed as well: see: https://github.com/manyminds/api2go/issues/301
24+
e.HTTPErrorHandler = customHTTPErrorHandler
25+
return routing.Echo(e)
26+
}
27+
28+
func init() {
29+
log.Println("Testing with echo router")
30+
}

gingonic_router_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build gingonic,!gorillamux
1+
// +build gingonic,!gorillamux,!echo
22

33
package api2go
44

gorillamux_router_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build !gingonic,gorillamux
1+
// +build !gingonic,!echo,gorillamux
22

33
package api2go
44

httprouter_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build !gingonic,!gorillamux
1+
// +build !gingonic,!gorillamux,!echo
22

33
package api2go
44

routing/echo.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// +build echo,!gorillamux,!gingonic
2+
3+
package routing
4+
5+
import (
6+
"net/http"
7+
8+
"github.com/labstack/echo"
9+
)
10+
11+
type echoRouter struct {
12+
echo *echo.Echo
13+
}
14+
15+
func (e echoRouter) Handler() http.Handler {
16+
return e.echo
17+
}
18+
19+
func (e echoRouter) Handle(protocol, route string, handler HandlerFunc) {
20+
echoHandlerFunc := func(c echo.Context) error {
21+
params := map[string]string{}
22+
23+
for i, p := range c.ParamNames() {
24+
params[p] = c.ParamValues()[i]
25+
}
26+
27+
handler(c.Response(), c.Request(), params)
28+
29+
return nil
30+
}
31+
e.echo.Add(protocol, route, echoHandlerFunc)
32+
}
33+
34+
// Echo created a new api2go router to use with the echo framework
35+
func Echo(e *echo.Echo) Routeable {
36+
return &echoRouter{echo: e}
37+
}

routing/echo_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// +build echo,!gingonic,!gorillamux
2+
3+
package routing_test
4+
5+
import (
6+
"io/ioutil"
7+
"log"
8+
"net/http"
9+
"net/http/httptest"
10+
"strings"
11+
12+
"github.com/labstack/echo"
13+
"github.com/manyminds/api2go"
14+
"github.com/manyminds/api2go/examples/model"
15+
"github.com/manyminds/api2go/examples/resource"
16+
"github.com/manyminds/api2go/examples/storage"
17+
"github.com/manyminds/api2go/routing"
18+
19+
. "github.com/onsi/ginkgo"
20+
. "github.com/onsi/gomega"
21+
)
22+
23+
var _ = Describe("api2go with echo router adapter", func() {
24+
var (
25+
router routing.Routeable
26+
e *echo.Echo
27+
api *api2go.API
28+
rec *httptest.ResponseRecorder
29+
)
30+
31+
BeforeSuite(func() {
32+
e = echo.New()
33+
router = routing.Echo(e)
34+
api = api2go.NewAPIWithRouting(
35+
"api",
36+
api2go.NewStaticResolver("/"),
37+
router,
38+
)
39+
40+
userStorage := storage.NewUserStorage()
41+
chocStorage := storage.NewChocolateStorage()
42+
api.AddResource(model.User{}, resource.UserResource{ChocStorage: chocStorage, UserStorage: userStorage})
43+
api.AddResource(model.Chocolate{}, resource.ChocolateResource{ChocStorage: chocStorage, UserStorage: userStorage})
44+
})
45+
46+
BeforeEach(func() {
47+
log.SetOutput(ioutil.Discard)
48+
rec = httptest.NewRecorder()
49+
})
50+
51+
Context("CRUD Tests", func() {
52+
It("will create a new user", func() {
53+
reqBody := strings.NewReader(`{"data": {"attributes": {"user-name": "Sansa Stark"}, "id": "1", "type": "users"}}`)
54+
req, err := http.NewRequest("POST", "/api/users", reqBody)
55+
Expect(err).To(BeNil())
56+
e.ServeHTTP(rec, req)
57+
Expect(rec.Code).To(Equal(http.StatusCreated))
58+
})
59+
60+
It("will find her", func() {
61+
expectedUser := `
62+
{
63+
"data":
64+
{
65+
"attributes":{
66+
"user-name":"Sansa Stark"
67+
},
68+
"id":"1",
69+
"relationships":{
70+
"sweets":{
71+
"data":[],"links":{"related":"/api/users/1/sweets","self":"/api/users/1/relationships/sweets"}
72+
}
73+
},"type":"users"
74+
},
75+
"meta":
76+
{
77+
"author":"The api2go examples crew","license":"wtfpl","license-url":"http://www.wtfpl.net"
78+
}
79+
}`
80+
81+
req, err := http.NewRequest("GET", "/api/users/1", nil)
82+
Expect(err).To(BeNil())
83+
e.ServeHTTP(rec, req)
84+
Expect(rec.Code).To(Equal(http.StatusOK))
85+
Expect(string(rec.Body.Bytes())).To(MatchJSON((expectedUser)))
86+
})
87+
88+
It("can call handle", func() {
89+
handler := api.Handler()
90+
_, ok := handler.(http.Handler)
91+
Expect(ok).To(Equal(true))
92+
})
93+
94+
It("update the username", func() {
95+
reqBody := strings.NewReader(`{"data": {"id": "1", "attributes": {"user-name": "Alayne"}, "type" : "users"}}`)
96+
req, err := http.NewRequest("PATCH", "/api/users/1", reqBody)
97+
Expect(err).To(BeNil())
98+
e.ServeHTTP(rec, req)
99+
Expect(rec.Code).To(Equal(http.StatusNoContent))
100+
})
101+
102+
It("will find her once again", func() {
103+
expectedUser := `
104+
{
105+
"data":
106+
{
107+
"attributes":{
108+
"user-name":"Alayne"
109+
},
110+
"id":"1",
111+
"relationships":{
112+
"sweets":{
113+
"data":[],"links":{"related":"/api/users/1/sweets","self":"/api/users/1/relationships/sweets"}
114+
}
115+
},"type":"users"
116+
},
117+
"meta":
118+
{
119+
"author":"The api2go examples crew","license":"wtfpl","license-url":"http://www.wtfpl.net"
120+
}
121+
}`
122+
123+
req, err := http.NewRequest("GET", "/api/users/1", nil)
124+
Expect(err).To(BeNil())
125+
e.ServeHTTP(rec, req)
126+
Expect(rec.Code).To(Equal(http.StatusOK))
127+
Expect(string(rec.Body.Bytes())).To(MatchJSON((expectedUser)))
128+
})
129+
130+
It("will delete her", func() {
131+
req, err := http.NewRequest("DELETE", "/api/users/1", nil)
132+
Expect(err).To(BeNil())
133+
e.ServeHTTP(rec, req)
134+
Expect(rec.Code).To(Equal(http.StatusNoContent))
135+
})
136+
137+
It("won't find her anymore", func() {
138+
expected := `{"errors":[{"status":"404","title":"http error (404) User for id 1 not found and 0 more errors, User for id 1 not found"}]}`
139+
req, err := http.NewRequest("GET", "/api/users/1", nil)
140+
Expect(err).To(BeNil())
141+
e.ServeHTTP(rec, req)
142+
Expect(rec.Code).To(Equal(http.StatusNotFound))
143+
Expect(string(rec.Body.Bytes())).To(MatchJSON(expected))
144+
})
145+
})
146+
})

routing/gingonic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build gingonic,!gorillamux
1+
// +build gingonic,!gorillamux,!echo
22

33
package routing
44

routing/gingonic_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build gingonic,!gorillamux
1+
// +build gingonic,!gorillamux,!echo
22

33
package routing_test
44

0 commit comments

Comments
 (0)