# Guide <!--- Some info about guide --> --- ## Installation Echo has been developed and tested using Go `1.4.x` Install the latest version of Echo via `go get` ```sh $ go get github.com/labstack/echo ``` To upgrade ```sh $ go get -u github.com/labstack/echo ``` Echo follows [semantic versioning](http://semver.org) managed through GitHub releases. Specific version of Echo can be installed using any [package manager](https://github.com/avelino/awesome-go#package-management). ## Customization ### HTTP error handler `Echo.SetHTTPErrorHandler(h HTTPErrorHandler)` Registers a custom `Echo.HTTPErrorHandler`. Default handler rules - If error is of type `Echo.HTTPError` it sends HTTP response with status code `HTTPError.Code` and message `HTTPError.Message`. - Else it sends `500 - Internal Server Error`. - If debug mode is enabled, it uses `error.Error()` as status message. ### Debug `Echo.SetDebug(on bool)` Enables debug mode. ## Routing Echo's router is [fast, optimized](https://github.com/labstack/echo#benchmark) and flexible. It's based on [redix tree](http://en.wikipedia.org/wiki/Radix_tree) data structure which makes routing lookup really fast. It leverages [sync pool](https://golang.org/pkg/sync/#Pool) to reuse memory and achieve zero dynamic memory allocation with no GC overhead. Routes can be registered by specifying HTTP method, path and a handler. For example, code below registers a route for method `GET`, path `/hello` and a handler which sends `Hello!` HTTP response. ```go echo.Get("/hello", func(c *echo.Context) error { return c.String(http.StatusOK, "Hello!") }) ``` Echo's default handler is `func(*echo.Context) error` where `echo.Context` primarily holds HTTP request and response objects. Echo also has a support for other types of handlers. ### Path parameter Request path parameters can be extracted either by name `Echo.Context.Param(name string) string` or by index `Echo.Context.P(i int) string`. Getting parameter by index gives a slightly better performance. ```go echo.Get("/users/:id", func(c *echo.Context) error { // By name id := c.Param("id") // By index id := c.P(0) return c.String(http.StatusOK, id) }) ``` ### Match-any Matches zero or more characters in the path. For example, pattern `/users/*` will match - `/users/` - `/users/1` - `/users/1/files/1` - `/users/anything...` ### Path matching order - Static - Param - Match any #### Example ```go e.Get("/users/:id", func(c *echo.Context) error { return c.String(http.StatusOK, "/users/:id") }) e.Get("/users/new", func(c *echo.Context) error { return c.String(http.StatusOK, "/users/new") }) e.Get("/users/1/files/*", func(c *echo.Context) error { return c.String(http.StatusOK, "/users/1/files/*") }) ``` Above routes would resolve in order - `/users/new` - `/users/:id` - `/users/1/files/*` Routes can be written in any order. ### Group `Echo.Group(prefix string, m ...Middleware) *Group` Routes with common prefix can be grouped to define a new sub-router with optional middleware. If middleware is passed to the function, it overrides parent middleware - helpful if you want a completely new middleware stack for the group. To add middleware later you can use `Group.Use(m ...Middleware)`. Groups can also be nested. In the code below, we create an admin group which requires basic HTTP authentication for routes `/admin/*`. ```go echo.Group("/admin") e.Use(mw.BasicAuth(func(usr, pwd string) bool { if usr == "joe" && pwd == "secret" { return true } return false })) ``` ### URI building `Echo.URI` can be used generate URI for any handler with specified path parameters. It's helpful to centralize all your URI patterns which ease in refactoring your application. `echo.URI(h, 1)` will generate `/users/1` for the route registered below ```go // Handler h := func(*echo.Context) error { return c.String(http.StatusOK, "OK") } // Route e.Get("/users/:id", h) ``` ## Middleware Middleware is function which is chained in the HTTP request-response cycle. Middleware has access to the request and response objects which it utilizes to perform a specific action for example, logging every request. Echo supports variety of [middleware](/#features). ### Logger Logs each HTTP request with method, path, status, response time and bytes served. *Example* ```go e.Use(Logger()) // Output: `2015/06/07 18:16:16 GET / 200 13.238µs 14` ``` ### BasicAuth BasicAuth middleware provides an HTTP basic authentication. - For valid credentials it calls the next handler in the chain. - For invalid Authorization header it sends "404 - Bad Request" response. - For invalid credentials, it sends "401 - Unauthorized" response. *Example* ```go echo.Group("/admin") e.Use(mw.BasicAuth(func(usr, pwd string) bool { if usr == "joe" && pwd == "secret" { return true } return false })) ``` ### Gzip Gzip middleware compresses HTTP response using gzip compression scheme. *Example* ```go e.Use(mw.Gzip()) ``` ### Recover Recover middleware recovers from panics anywhere in the chain and handles the control to the centralized [HTTPErrorHandler](#error-handling). *Example* ```go e.Use(mw.Recover()) ``` ### StripTrailingSlash StripTrailingSlash middleware removes the trailing slash from request path. *Example* ```go e.Use(mw.StripTrailingSlash()) ``` ### RedirectToSlash RedirectToSlash middleware redirects requests without trailing slash path to trailing slash path. *Options* ```go RedirectToSlashOptions struct { Code int } ``` *Example* ```go e.Use(mw.RedirectToSlash()) ``` > StripTrailingSlash and RedirectToSlash middleware should not be used together. [Examples](https://github.com/labstack/echo/tree/master/examples/middleware) ## Response ### JSON ```go context.JSON(code int, v interface{}) error ``` Sends a JSON HTTP response with status code. ### String ```go context.String(code int, s string) error ``` Sends a text/plain HTTP response with status code. ### HTML ```go func (c *Context) HTML(code int, html string) error ``` Sends an HTML HTTP response with status code. ### Static files `Echo.Static(path, root string)` serves static files. For example, code below serves files from directory `public/scripts` for any request path starting with `/scripts/`. ```go e.Static("/scripts/", "public/scripts") ``` ### Serving a file `Echo.ServeFile(path, file string)` serves a file. For example, code below serves file `welcome.html` for request path `/welcome`. ```go e.ServeFile("/welcome", "welcome.html") ``` ### Serving an index file `Echo.Index(file string)` serves root index page - `GET /`. For example, code below serves root index page from file `public/index.html`. ```go e.Index("public/index.html") ``` ### Serving favicon `Echo.Favicon(file string)` serves default favicon - `GET /favicon.ico`. For example, code below serves favicon from file `public/favicon.ico`. ```go e.Favicon("public/favicon.ico") ``` ## Error Handling Echo advocates centralized HTTP error handling by returning `error` from middleware and handlers. It allows you to - Debug by writing stack trace to the HTTP response. - Customize HTTP responses. - Recover from panics inside middleware or handlers. For example, when basic auth middleware finds invalid credentials it returns `401 - Unauthorized` error, aborting the current HTTP request. ```go package main import ( "net/http" "github.com/labstack/echo" ) func main() { e := echo.New() e.Use(func(c *echo.Context) error { // Extract the credentials from HTTP request header and perform a security // check // For invalid credentials return echo.NewHTTPError(http.StatusUnauthorized) }) e.Get("/welcome", welcome) e.Run(":1323") } func welcome(c *echo.Context) error { return c.String(http.StatusOK, "Welcome!") } ``` See how [HTTPErrorHandler](#customization) handles it. ## Deployment *WIP*