Skip to main content

Echo Context

Introduction

In the Echo framework, the Context object is one of the most important concepts you'll work with. It represents the context of the current HTTP request and response, encapsulating essential information and providing methods to interact with the client. Understanding how to effectively use the Echo Context is fundamental to building robust web applications with the Echo framework.

The Context acts as a bridge between your application code and the HTTP transaction, allowing you to:

  • Access request data
  • Send responses
  • Access path parameters
  • Set and get values for middleware sharing
  • Handle cookies and sessions
  • Manage file uploads and downloads

Core Concepts of Echo Context

What is a Context?

In Echo, a Context (echo.Context) is an interface that wraps an HTTP request and response. It's automatically created by the Echo framework for each incoming request and passed to your handler functions.

go
// Basic handler function signature in Echo
func(c echo.Context) error

This context-based approach makes your handlers clean and focused while providing access to everything related to the current HTTP transaction.

Context Methods

Echo Context provides numerous methods for different purposes. Let's explore some of the most common ones:

Accessing Request Data

go
// Handler function
func getUser(c echo.Context) error {
// Get query parameters
name := c.QueryParam("name")

// Get form parameters
email := c.FormValue("email")

// Get path parameters
id := c.Param("id")

// Get request headers
userAgent := c.Request().Header.Get("User-Agent")

// Access the raw http.Request
request := c.Request()

return c.String(http.StatusOK, fmt.Sprintf("User %s with ID %s and email %s", name, id, email))
}

Example Usage:

go
// Route registration
e.GET("/users/:id", getUser)

When accessing /users/123?name=John with a form containing [email protected]:

Output:

User John with ID 123 and email [email protected]

Sending Responses

Echo Context provides multiple convenient methods to send different types of responses:

go
// String response
func handleString(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
}

// JSON response
func handleJSON(c echo.Context) error {
user := struct {
Name string `json:"name"`
Email string `json:"email"`
}{
Name: "John Doe",
Email: "[email protected]",
}
return c.JSON(http.StatusOK, user)
}

// HTML response
func handleHTML(c echo.Context) error {
return c.HTML(http.StatusOK, "<h1>Hello, World!</h1>")
}

// File response
func handleFile(c echo.Context) error {
return c.File("path/to/file.pdf")
}

// Blob response
func handleBlob(c echo.Context) error {
data := []byte{0x89, 0x50, 0x4E, 0x47}
return c.Blob(http.StatusOK, "image/png", data)
}

// Stream response
func handleStream(c echo.Context) error {
file, err := os.Open("large_file.mp4")
if err != nil {
return err
}
defer file.Close()

return c.Stream(http.StatusOK, "video/mp4", file)
}

Working with Path Parameters

Path parameters are parts of the URL path that can be captured as variables:

go
// Define a route with path parameters
// e.GET("/users/:id/posts/:postId", handleUserPost)

func handleUserPost(c echo.Context) error {
userId := c.Param("id")
postId := c.Param("postId")

return c.String(http.StatusOK, fmt.Sprintf("Fetching post %s for user %s", postId, userId))
}

Example Usage: When accessing /users/42/posts/123:

Output:

Fetching post 123 for user 42

Context Values for Data Sharing

Echo Context allows you to store and retrieve values that can be shared across middleware and handlers:

go
// Middleware that sets a value in context
func AuthMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
// Pretend we've authenticated a user
userId := "user_12345"
c.Set("userId", userId)
c.Set("authenticated", true)
return next(c)
}
}

// Handler that uses the values from context
func protectedHandler(c echo.Context) error {
userId := c.Get("userId").(string)
isAuthenticated := c.Get("authenticated").(bool)

if !isAuthenticated {
return c.String(http.StatusUnauthorized, "Not authenticated")
}

return c.String(http.StatusOK, fmt.Sprintf("Welcome, user %s!", userId))
}

Practical Examples

Example 1: Creating a REST API Endpoint

go
package main

import (
"net/http"

"github.com/labstack/echo/v4"
)

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

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

// GET endpoint to fetch user details
e.GET("/api/users/:id", func(c echo.Context) error {
id := c.Param("id")

// In a real application, you would fetch this from a database
user := User{
ID: id,
Name: "Jane Doe",
Email: "[email protected]",
}

return c.JSON(http.StatusOK, user)
})

// POST endpoint to create a user
e.POST("/api/users", func(c echo.Context) error {
user := new(User)
if err := c.Bind(user); err != nil {
return c.String(http.StatusBadRequest, "Invalid request payload")
}

// In a real application, you would save this to a database
// and generate a real ID
user.ID = "new_id_12345"

return c.JSON(http.StatusCreated, user)
})

e.Logger.Fatal(e.Start(":8080"))
}

Sample Input for POST:

json
{
"name": "John Smith",
"email": "[email protected]"
}

Expected Output:

json
{
"id": "new_id_12345",
"name": "John Smith",
"email": "[email protected]"
}

Example 2: Creating a Custom Context

Sometimes you may want to extend the Echo Context with additional methods or data. Echo allows you to create custom contexts:

go
package main

import (
"net/http"

"github.com/labstack/echo/v4"
)

// CustomContext extends echo.Context
type CustomContext struct {
echo.Context
// Add custom fields
UserID string
}

// CustomContextMiddleware creates a middleware that sets up our custom context
func CustomContextMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cc := &CustomContext{
Context: c,
}
return next(cc)
}
}

// Handler that uses our custom context
func welcomeHandler(c echo.Context) error {
// Type assertion to access our custom context
cc := c.(*CustomContext)

// Set a value in our custom context
cc.UserID = "12345"

return c.String(http.StatusOK, "Welcome! Your ID is "+cc.UserID)
}

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

// Apply our custom context middleware
e.Use(CustomContextMiddleware)

// Register route
e.GET("/welcome", welcomeHandler)

e.Logger.Fatal(e.Start(":8080"))
}

Working with Cookies

Echo Context provides easy methods to handle cookies:

go
// Set a cookie
func setCookieHandler(c echo.Context) error {
cookie := new(http.Cookie)
cookie.Name = "username"
cookie.Value = "john_doe"
cookie.Expires = time.Now().Add(24 * time.Hour)
c.SetCookie(cookie)
return c.String(http.StatusOK, "Cookie set!")
}

// Get a cookie
func getCookieHandler(c echo.Context) error {
cookie, err := c.Cookie("username")
if err != nil {
return c.String(http.StatusBadRequest, "Cookie not found")
}
return c.String(http.StatusOK, "Cookie value: "+cookie.Value)
}

File Upload Handling

Echo makes it easy to handle file uploads:

go
func uploadHandler(c echo.Context) error {
// Get the file from the request
file, err := c.FormFile("document")
if err != nil {
return err
}

// Source file
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()

// Destination file
dst, err := os.Create("uploads/" + file.Filename)
if err != nil {
return err
}
defer dst.Close()

// Copy the uploaded file to the destination file
if _, err = io.Copy(dst, src); err != nil {
return err
}

return c.HTML(http.StatusOK, fmt.Sprintf("<p>File %s uploaded successfully.</p>", file.Filename))
}

Summary

The Echo Context is a central component of the Echo framework that provides access to the HTTP request and response. It offers numerous methods to:

  • Extract data from the request (query parameters, path parameters, form data, headers)
  • Send various types of responses (JSON, HTML, XML, files, etc.)
  • Share data between middleware and handlers
  • Manage cookies and sessions
  • Handle file uploads and downloads

Understanding how to effectively use the Echo Context is essential for developing clean, efficient, and feature-rich web applications with the Echo framework.

Additional Resources

Exercises

  1. Create a simple API endpoint that takes a user's name as a query parameter and returns a personalized greeting as JSON.
  2. Implement a middleware that logs the request method, path, and duration for each request.
  3. Create an endpoint that accepts file uploads and validates that only image files (PNG, JPG) are accepted.
  4. Build a RESTful API for a to-do list application with endpoints for creating, reading, updating, and deleting to-do items.
  5. Implement session management using cookies in an Echo application.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)