Echo
02 / 02

Middleware, Errors & Static Files

Middleware, Errors & Static Files

Global vs. Per-Route Middleware

e := echo.New()
e.Use(middleware.Logger())    // every incoming request
e.Use(middleware.Recover())   // panic -> 500 instead of crashing the process
e.Use(middleware.CORS())

// per-route: pass middleware after the handler
e.GET("/admin", adminHandler, authMiddleware)

Middleware wraps the handler chain, executing in registration order — each typically calls next() before/after its own logic. middleware.Recover() isolates a panic to just that one request rather than crashing the whole server.

Centralized Error Handling

func getUser(c echo.Context) error {
  user, err := findUser(c.Param("id"))
  if err != nil {
    return echo.NewHTTPError(http.StatusNotFound, "user not found")
  }
  return c.JSON(http.StatusOK, user)
}

// main() — one place formats every error response consistently
e.HTTPErrorHandler = func(err error, c echo.Context) {
  code := http.StatusInternalServerError
  if he, ok := err.(*echo.HTTPError); ok {
    code = he.Code
  }
  c.JSON(code, map[string]string{"error": err.Error()})
}

Static Files

e.Static("/static", "assets")  // serves files from ./assets under /static/*

Why Echo Over Plain net/http

net/http alone is fully capable, but Echo reduces boilerplate: flexible path-param routing, a built-in middleware ecosystem (logging, recovery, CORS, rate limiting), and binding/response helpers — versus hand-assembling equivalents from separate packages.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free