REST API with Echo

You build a REST API with Echo by initializing an `echo.Echo` instance, defining routes with HTTP methods, and attaching handler functions that read request data and write JSON responses.

You build a REST API with Echo by initializing an echo.Echo instance, defining routes with HTTP methods, and attaching handler functions that read request data and write JSON responses. The framework automatically handles content negotiation, middleware chaining, and error formatting, allowing you to focus on business logic.

Here is a minimal example creating a user service with GET and POST endpoints:

package main

import (
	"net/http"
	"github.com/labstack/echo/v4"
)

type User struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func main() {
	e := echo.New()

	// GET /users/:id
	e.GET("/users/:id", func(c echo.Context) error {
		id := c.Param("id")
		user := User{ID: 1, Name: "Alice"} // Fetch from DB in real app
		return c.JSON(http.StatusOK, user)
	})

	// POST /users
	e.POST("/users", func(c echo.Context) error {
		var user User
		if err := c.Bind(&user); err != nil {
			return err
		}
		// Save to DB in real app
		return c.JSON(http.StatusCreated, user)
	})

	e.Start(":8080")
}

For production, you should add middleware for logging, recovery, and CORS. Echo provides these out of the box. Here is how to configure a robust server setup:

package main

import (
	"net/http"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

func main() {
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	e.Use(middleware.CORS())

	// Routes
	e.GET("/health", func(c echo.Context) error {
		return c.String(http.StatusOK, "OK")
	})

	// Error handling
	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()})
	}

	e.Start(":8080")
}

Echo uses a fluent interface for routing, making it easy to group routes by version or resource. You can use e.Group("/v1") to prefix routes, which is essential for API versioning. The c.Bind() method automatically parses JSON bodies into structs, while c.Param() extracts path variables. If you need query parameters, use c.QueryParam("key").

Error handling is centralized via e.HTTPErrorHandler. By default, Echo returns a JSON error object, but you can customize this to match your API standards. For authentication, simply add middleware like middleware.JWT() before your protected routes. The framework's modular design means you only import what you need, keeping the binary size small and startup time fast.