Building an API with Echo
Why Echo?
Section titled “Why Echo?”If you come from Node.js you already think in terms of a lightweight HTTP framework: a function that maps a path + verb to a handler, a middleware pipeline, and a way to serialize JSON. Echo is that framework for Go.
| Concern | Node.js / Express | Go / Echo |
|---|---|---|
| Core abstraction | (req, res, next) functions | func(c echo.Context) error |
| Routing | app.get('/path', handler) | e.GET("/path", handler) |
| Middleware | app.use(fn) | e.Use(fn) |
| JSON response | res.json({ … }) | c.JSON(200, payload) |
| Error propagation | next(err) | return err |
Echo competes with frameworks like Fastify and NestJS in spirit, but it is a single compiled binary with no runtime, no VM, and no node_modules. Cold-start time is microseconds, not seconds.
Echo vs the Go ecosystem
Section titled “Echo vs the Go ecosystem”Go has several web frameworks (Gin, Chi, Fiber, stdlib net/http). Echo sits in the sweet spot:
- Minimal surface area — you can read the entire source in a weekend.
- Idiomatic — handlers return
error; Go’s error-as-value pattern maps directly. - Rich built-ins — Logger, Recover, CORS, GZIP, BasicAuth out of the box.
- Stable — Echo v4 has been production-hardened for years.
// Express (Node.js)import express from 'express';const app = express();app.use(express.json());
app.get('/ping', (req, res) => { res.json({ message: 'pong' });});
app.listen(1323, () => console.log('listening'));// Echo (Go)package main
import ( "net/http" "github.com/labstack/echo/v4")
func main() { e := echo.New()
e.GET("/ping", func(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{ "message": "pong", }) })
e.Logger.Fatal(e.Start(":1323"))}What you will build
Section titled “What you will build”Throughout this module you will build a small Books REST API — create, read, update, and delete books — step by step:
- Scaffold a project with
go.modandmain.go. - Define routes and handler functions.
- Add middleware (logging, recovery, CORS).
- Bind request bodies and validate them with struct tags.
- Shape JSON responses with status codes.
- Handle errors centrally — the Go way.
- Touch a database via
database/sql. - Write handler tests with
httptest.
Each lesson is self-contained. You can jump in at any step, but the project grows progressively.