Skip to content

Commit

Permalink
Merge pull request #76 from labstack/websocket
Browse files Browse the repository at this point in the history
New definition for Echo.HandlerFunc
  • Loading branch information
vishr committed May 20, 2015
2 parents a451812 + 1ad37ae commit 1e11762
Show file tree
Hide file tree
Showing 23 changed files with 267 additions and 215 deletions.
53 changes: 25 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Echo is a fast HTTP router (zero memory allocation) and micro web framework in G
- `echo.MiddlewareFunc`
- `func(echo.HandlerFunc) echo.HandlerFunc`
- `echo.HandlerFunc`
- `func(*echo.Context) *echo.HTTPError`
- `func(*echo.Context) error`
- `func(http.Handler) http.Handler`
- `http.Handler`
- `http.HandlerFunc`
- `func(http.ResponseWriter, *http.Request)`
- Handler
- `echo.HandlerFunc`
- `func(*echo.Context) *echo.HTTPError`
- `func(*echo.Context) error`
- `http.Handler`
- `http.HandlerFunc`
- `func(http.ResponseWriter, *http.Request)`
Expand Down Expand Up @@ -84,7 +84,7 @@ import (
)

// Handler
func hello(c *echo.Context) *echo.HTTPError {
func hello(c *echo.Context) error {
return c.String(http.StatusOK, "Hello, World!\n")
}

Expand Down Expand Up @@ -133,34 +133,34 @@ var (
// Handlers
//----------

func createUser(c *echo.Context) *echo.HTTPError {
func createUser(c *echo.Context) error {
u := &user{
ID: seq,
}
if he := c.Bind(u); he != nil {
return he
if err := c.Bind(u); err != nil {
return err
}
users[u.ID] = u
seq++
return c.JSON(http.StatusCreated, u)
}

func getUser(c *echo.Context) *echo.HTTPError {
func getUser(c *echo.Context) error {
id, _ := strconv.Atoi(c.Param("id"))
return c.JSON(http.StatusOK, users[id])
}

func updateUser(c *echo.Context) *echo.HTTPError {
func updateUser(c *echo.Context) error {
u := new(user)
if he := c.Bind(u); he != nil {
return he
if err := c.Bind(u); err != nil {
return err
}
id, _ := strconv.Atoi(c.Param("id"))
users[id].Name = u.Name
return c.JSON(http.StatusOK, users[id])
}

func deleteUser(c *echo.Context) *echo.HTTPError {
func deleteUser(c *echo.Context) error {
id, _ := strconv.Atoi(c.Param("id"))
delete(users, id)
return c.NoContent(http.StatusNoContent)
Expand Down Expand Up @@ -218,22 +218,19 @@ var (
)

// Render HTML
func (t *Template) Render(w io.Writer, name string, data interface{}) *echo.HTTPError {
if err := t.templates.ExecuteTemplate(w, name, data); err != nil {
return &echo.HTTPError{Error: err}
}
return nil
func (t *Template) Render(w io.Writer, name string, data interface{}) error {
return t.templates.ExecuteTemplate(w, name, data)
}

//----------
// Handlers
//----------

func welcome(c *echo.Context) *echo.HTTPError {
func welcome(c *echo.Context) error {
return c.Render(http.StatusOK, "welcome", "Joe")
}

func createUser(c *echo.Context) *echo.HTTPError {
func createUser(c *echo.Context) error {
u := new(user)
if err := c.Bind(u); err != nil {
return err
Expand All @@ -242,11 +239,11 @@ func createUser(c *echo.Context) *echo.HTTPError {
return c.JSON(http.StatusCreated, u)
}

func getUsers(c *echo.Context) *echo.HTTPError {
func getUsers(c *echo.Context) error {
return c.JSON(http.StatusOK, users)
}

func getUser(c *echo.Context) *echo.HTTPError {
func getUser(c *echo.Context) error {
return c.JSON(http.StatusOK, users[c.P(0)])
}

Expand All @@ -268,7 +265,7 @@ func main() {
s := stats.New()
e.Use(s.Handler)
// Route
e.Get("/stats", func(c *echo.Context) *echo.HTTPError {
e.Get("/stats", func(c *echo.Context) error {
return c.JSON(http.StatusOK, s.Data())
})

Expand Down Expand Up @@ -297,7 +294,7 @@ func main() {
// Cached templates
templates: template.Must(template.ParseFiles("public/views/welcome.html")),
}
e.Renderer(t)
e.SetRenderer(t)
e.Get("/welcome", welcome)

//-------
Expand All @@ -306,20 +303,20 @@ func main() {

// Group with parent middleware
a := e.Group("/admin")
a.Use(func(c *echo.Context) *echo.HTTPError {
a.Use(func(c *echo.Context) error {
// Security middleware
return nil
})
a.Get("", func(c *echo.Context) *echo.HTTPError {
a.Get("", func(c *echo.Context) error {
return c.String(http.StatusOK, "Welcome admin!")
})

// Group with no parent middleware
g := e.Group("/files", func(c *echo.Context) *echo.HTTPError {
g := e.Group("/files", func(c *echo.Context) error {
// Security middleware
return nil
})
g.Get("", func(c *echo.Context) *echo.HTTPError {
g.Get("", func(c *echo.Context) error {
return c.String(http.StatusOK, "Your files!")
})

Expand Down Expand Up @@ -350,7 +347,7 @@ import (
)

// Handler
func hello(c *echo.Context) *echo.HTTPError {
func hello(c *echo.Context) error {
return c.String(http.StatusOK, "Hello, World!\n")
}

Expand All @@ -359,7 +356,7 @@ func main() {
e := echo.New()

// Debug mode
e.Debug(true)
e.SetDebug(true)

//------------
// Middleware
Expand Down
38 changes: 17 additions & 21 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package echo
import (
"encoding/json"
"net/http"

"golang.org/x/net/websocket"
)

type (
Expand All @@ -11,6 +13,7 @@ type (
Context struct {
Request *http.Request
Response *Response
Socket *websocket.Conn
pnames []string
pvalues []string
store store
Expand Down Expand Up @@ -53,60 +56,53 @@ func (c *Context) Param(name string) (value string) {

// Bind binds the request body into specified type v. Default binder does it
// based on Content-Type header.
func (c *Context) Bind(i interface{}) *HTTPError {
func (c *Context) Bind(i interface{}) error {
return c.echo.binder(c.Request, i)
}

// Render invokes the registered HTML template renderer and sends a text/html
// response with status code.
func (c *Context) Render(code int, name string, data interface{}) *HTTPError {
func (c *Context) Render(code int, name string, data interface{}) error {
if c.echo.renderer == nil {
return &HTTPError{Error: RendererNotRegistered}
return RendererNotRegistered
}
c.Response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.Response.WriteHeader(code)
return c.echo.renderer.Render(c.Response, name, data)
}

// JSON sends an application/json response with status code.
func (c *Context) JSON(code int, i interface{}) *HTTPError {
func (c *Context) JSON(code int, i interface{}) error {
c.Response.Header().Set(ContentType, ApplicationJSON+"; charset=utf-8")
c.Response.WriteHeader(code)
if err := json.NewEncoder(c.Response).Encode(i); err != nil {
return &HTTPError{Error: err}
}
return nil
return json.NewEncoder(c.Response).Encode(i)
}

// String sends a text/plain response with status code.
func (c *Context) String(code int, s string) *HTTPError {
func (c *Context) String(code int, s string) error {
c.Response.Header().Set(ContentType, TextPlain+"; charset=utf-8")
c.Response.WriteHeader(code)
if _, err := c.Response.Write([]byte(s)); err != nil {
return &HTTPError{Error: err}
}
return nil
_, err := c.Response.Write([]byte(s))
return err
}

// HTML sends a text/html response with status code.
func (c *Context) HTML(code int, html string) *HTTPError {
func (c *Context) HTML(code int, html string) error {
c.Response.Header().Set(ContentType, TextHTML+"; charset=utf-8")
c.Response.WriteHeader(code)
if _, err := c.Response.Write([]byte(html)); err != nil {
return &HTTPError{Error: err}
}
return nil
_, err := c.Response.Write([]byte(html))
return err
}

// NoContent sends a response with no body and a status code.
func (c *Context) NoContent(code int) *HTTPError {
func (c *Context) NoContent(code int) error {
c.Response.WriteHeader(code)
return nil
}

// Error invokes the registered HTTP error handler.
func (c *Context) Error(he *HTTPError) {
c.echo.httpErrorHandler(he, c)
func (c *Context) Error(err error) {
c.echo.httpErrorHandler(err, c)
}

// Get retrieves data from the context.
Expand Down
9 changes: 3 additions & 6 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,14 @@ type (
}
)

func (t *Template) Render(w io.Writer, name string, data interface{}) *HTTPError {
if err := t.templates.ExecuteTemplate(w, name, data); err != nil {
return &HTTPError{Error: err}
}
return nil
func (t *Template) Render(w io.Writer, name string, data interface{}) error {
return t.templates.ExecuteTemplate(w, name, data)
}

func TestContext(t *testing.T) {
b, _ := json.Marshal(u1)
r, _ := http.NewRequest(POST, "/users/1", bytes.NewReader(b))
c := NewContext(r, &Response{Writer: httptest.NewRecorder()}, New())
c := NewContext(r, NewResponse(httptest.NewRecorder()), New())

//------
// Bind
Expand Down
Loading

0 comments on commit 1e11762

Please sign in to comment.