Echo framework

 

Echo website

 
 

Features I liked about Echo

  1. Middleware
notion image
 
  1. Data binding
notion image
 
 

 

Tutorial

 

Routing

e.POST("/users", saveUser) e.GET("/users/:id", getUser) e.PUT("/users/:id", updateUser) e.DELETE("/users/:id", deleteUser)
 

Get :id by Param

// e.GET("/users/:id", getUser) func getUser(c echo.Context) error { // User ID from path `users/:id` id := c.Param("id") return c.String(http.StatusOK, id) }
Browse to http://localhost:1323/users/Joe and you should see ‘Joe’ on the page.
 

Query parameters

/show?team=x-men&member=wolverine
//e.GET("/show", show) func show(c echo.Context) error { // Get team and member from the query string team := c.QueryParam("team") member := c.QueryParam("member") return c.String(http.StatusOK, "team:" + team + ", member:" + member) }
Browse to http://localhost:1323/show?team=x-men&member=wolverine and you should see ’team:x-men, member:wolverine’ on the page.
 

Post

Form application/x-www-form-urlencoded

POST /save
name
value
name
Joe Smith
email
// e.POST("/save", save) func save(c echo.Context) error { // Get name and email name := c.FormValue("name") email := c.FormValue("email") return c.String(http.StatusOK, "name:" + name + ", email:" + email) }

Form multipart/form-data

POST /save
name
value
name
Joe Smith
avatar
avatar
Assume avator value is File
func save(c echo.Context) error { // Get name name := c.FormValue("name") // Get avatar avatar, err := c.FormFile("avatar") if err != nil { return err } // Source src, err := avatar.Open() if err != nil { return err } defer src.Close() // Destination dst, err := os.Create(avatar.Filename) if err != nil { return err } defer dst.Close() // Copy if _, err = io.Copy(dst, src); err != nil { return err } return c.HTML(http.StatusOK, "<b>Thank you! " + name + "</b>") }
 

Handling request

Handling all JSON, x-www-form-urlencoded, and form-data is annoying, but it can be handled at once by following the code.
  • Bind jsonxmlform or query payload into Go struct based on Content-Type request header.
  • Render response as json or xml with status code.
type User struct { Name string `json:"name" xml:"name" form:"name" query:"name"` Email string `json:"email" xml:"email" form:"email" query:"email"` } e.POST("/users", func(c echo.Context) error { u := new(User) if err := c.Bind(u); err != nil { return err } return c.JSON(http.StatusCreated, u) // or // return c.XML(http.StatusCreated, u) })
 

Middleware

List of middlewares →
// Root level middleware e.Use(middleware.Logger()) e.Use(middleware.Recover())
 

Response

JSON response

In CRUD API, we usually use JSON response.
 
// User type User struct { Name string `json:"name" xml:"name"` Email string `json:"email" xml:"email"` } // Handler func(c echo.Context) error { u := &User{ Name: "Jon", Email: "jon@labstack.com", } return c.JSON(http.StatusOK, u) }
 
 

Stream JSON ?

 
 

Pretty

💡
You can see JSON prettified by adding ?pretty at the end of url
Context#JSON()  internally uses json.Marshal  which may not be efficient to large JSON, in that case you can directly stream JSON.
 

Jaeger

 
 

Prometheus

 
 
 

Timeout

 
Set timeout to 30 seconds.
e := echo.New() e.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{ Skipper: Skipper, ErrorHandler: func(err error, e echo.Context) error { // you can handle your error here, the returning error will be // passed down the middleware chain return err }, Timeout: 30*time.Second, }))
 
 

Rate limiter

To add a rate limit to your application simply add the RateLimiter middlware. The example below will limit the application to 20 requests/sec using the default in-memory store:
e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(20)))
 

Secure