### Hello, World! Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/quickstart.md A basic 'Hello, World!' example demonstrating Echo's core setup, middleware usage, and starting the server. ```go package main import ( "net/http" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.GET("/", func(c *echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"message": "Hello, World!"}) }) if err := e.Start(":1323"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Run a Cookbook Recipe Example Source: https://github.com/labstack/echox/blob/master/README.md Commands to navigate to a specific cookbook recipe directory and run it using Go. Assumes Go is installed. ```bash cd cookbook/hello-world go run . ``` -------------------------------- ### Minimal Echo Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/hello-world.md Sets up a basic Echo server with Logger and Recover middleware, a root route, and starts the server. Ensure Echo is installed. ```go package main import ( "context" "net/http" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { // Echo instance e := echo.New() // Middleware e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) // Route => handler e.GET("/", func(c *echo.Context) error { return c.String(http.StatusOK, "Hello, World!\n") }) // Start server sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Full Example: Echo HTTP/2 Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2.md A complete Go program demonstrating how to set up an Echo server that handles requests over HTTP/2 using TLS. Includes a handler to display request information and starts the server with a certificate. ```go package main import ( "context" "fmt" "net/http" "github.com/labstack/echo/v5" ) func main() { e := echo.New() e.GET("/request", func(c *echo.Context) error { req := c.Request() format := ` Protocol: %s
Host: %s
Remote Address: %s
Method: %s
Path: %s
` return c.HTML(http.StatusOK, fmt.Sprintf(format, req.Proto, req.Host, req.RemoteAddr, req.Method, req.URL.Path)) }) sc := echo.StartConfig{Address: ":1323"} if err := sc.StartTLS(context.Background(), e, "cert.pem", "key.pem"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Basic Echo Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/index.mdx Create a new Echo instance, register a root route, and start the server on port 1323. This demonstrates the minimal setup for a running Echo application. ```go e := echo.New() e.GET("/", hello) e.Start(":1323") ``` -------------------------------- ### Install Prometheus Middleware Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/prometheus.md Install the echo-prometheus module using go get. ```bash go get github.com/labstack/echo-prometheus ``` -------------------------------- ### Install Gorilla Sessions Dependency Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md Install the gorilla/sessions package using go get. ```bash go get github.com/gorilla/sessions ``` -------------------------------- ### Install and Run Documentation Site Source: https://github.com/labstack/echox/blob/master/README.md Commands to install dependencies and run the development server for the documentation site. Requires Node.js. ```bash cd site npm install npm run dev # dev server at http://localhost:4321 npm run build # production build to site/dist npm run preview # preview the production build ``` -------------------------------- ### Install Echo Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/quickstart.md Initialize a new Go module and add the Echo framework dependency. ```bash go mod init myapp go get github.com/labstack/echo/v5 ``` -------------------------------- ### Full Example with Request ID Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/request-id.md A complete example demonstrating how to integrate the RequestID middleware and access the generated ID within a request handler. ```go func main() { e := echo.New() e.Use(middleware.RequestID()) e.GET("/", func(c *echo.Context) error { return c.String(http.StatusOK, c.Response().Header().Get(echo.HeaderXRequestID)) }) if err := e.Start(":8080"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Start Proxy Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/reverse-proxy.md Command to start the main Echo proxy server. ```sh go run server.go ``` -------------------------------- ### Install Casbin Dependency Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/casbin-auth.md Install the Casbin Go library using go get. ```bash go get github.com/casbin/casbin/v3 ``` -------------------------------- ### Start Custom HTTP Server with TLS Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2.md Configure and start a custom http.Server with Echo as the handler and custom TLS configuration. This provides more control over server settings like timeouts. ```go s := http.Server{ Addr: ":8443", Handler: e, // set Echo as handler TLSConfig: &tls.Config{ //Certificates: nil, // <-- s.ListenAndServeTLS will populate this field }, //ReadTimeout: 30 * time.Second, // use custom timeouts } if err := s.ListenAndServeTLS("cert.pem", "key.pem"); err != http.ErrServerClosed { log.Fatal(err) } ``` -------------------------------- ### Full Casbin + JWT Example in Go Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/casbin-auth.md A complete example demonstrating the integration of Casbin authorization with JWT authentication in an Echo application. ```go package main import ( "log/slog" "net/http" "github.com/casbin/casbin/v3" "github.com/golang-jwt/jwt/v5" echojwt "github.com/labstack/echo-jwt/v5" "github.com/labstack/echo/v5" ) // NewCasbinMiddleware returns middleware for Casbin (https://casbin.org/). func NewCasbinMiddleware(enforcer *casbin.Enforcer, userGetter func(*echo.Context) (string, error)) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { username, err := userGetter(c) if err != nil { return echo.ErrUnauthorized.Wrap(err) } if pass, err := enforcer.Enforce(username, c.Request().URL.Path, c.Request().Method); err != nil { return echo.ErrInternalServerError.Wrap(err) } else if !pass { return echo.NewHTTPError(http.StatusForbidden, "access denied") } return next(c) } } } func main() { e := echo.New() ce, err := casbin.NewEnforcer("auth_model.conf", "auth_policy.csv") if err != nil { slog.Error("failed to initialize Casbin enforcer", "error", err) } e.Use(echojwt.JWT([]byte("secret"))) jwtUser := func(c *echo.Context) (string, error) { // JWT user getter for Casbin authorization token, err := echo.ContextGet[*jwt.Token](c, "user") if err != nil { return "", err } return token.Claims.GetSubject() } e.Use(NewCasbinMiddleware(ce, jwtUser)) // Casbin does authorization e.GET("/*", func(c *echo.Context) error { return c.String(http.StatusOK, "Hello, World!") }) if err := e.Start(":8080"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Run Go Application Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/quickstart.md Execute the Go application to start the Echo server. ```bash go run main.go ``` -------------------------------- ### Start Echo TLS Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2.md Start the Echo server using a TLS certificate and key. This enables HTTP/2 communication. Ensure the certificate and key files are accessible. ```go sc := echo.StartConfig{Address: ":1323"} if err := sc.StartTLS(context.Background(), e, "cert.pem", "key.pem"); err != nil { e.Logger.Error("failed to start server", "error", err) } ``` -------------------------------- ### Serve All Files with Echo#Static() Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Serve all files from a directory under the root path. This example serves files from 'assets' under the '/' path. ```go e := echo.New() e.Static("/", "assets") ``` -------------------------------- ### Start Echo Server with Auto TLS Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/auto-tls.md Configure Echo's `StartConfig` with an autocert manager's `TLSConfig` to automatically obtain and renew TLS certificates from Let's Encrypt. This is suitable for basic Echo server setups listening on port 443. ```go package main import ( "context" "crypto/tls" "errors" "log/slog" "net/http" "os" "golang.org/x/crypto/acme" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" "golang.org/x/crypto/acme/autocert" ) func main() { e := echo.New() e.Logger = slog.New(slog.NewJSONHandler(os.Stdout, nil)) e.Use(middleware.Recover()) e.Use(middleware.RequestLogger()) e.GET("/", func(c *echo.Context) error { return c.HTML(http.StatusOK, `

Welcome to Echo!

TLS certificates automatically installed from Let's Encrypt :)

`) }) m := &autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist("example.com", "www.example.com"), // Cache certificates to avoid issues with rate limits (https://letsencrypt.org/docs/rate-limits) Cache: autocert.DirCache("/var/www/.cache"), // Email: "[email protected]", // optional but recommended } sc := echo.StartConfig{ Address: ":443", TLSConfig: m.TLSConfig(), } if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Client: Get User Request Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/crud.md Example of how to retrieve a specific user by their ID using a GET request. ```sh curl localhost:1323/users/1 ``` -------------------------------- ### Install OpenTelemetry Middleware Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/open-telemetry.md Install the echo-opentelemetry middleware dependency using Go modules. ```bash go get github.com/labstack/echo-opentelemetry ``` -------------------------------- ### Setting Query Parameters Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/testing.md Shows how to construct an HTTP GET request with query parameters using url.Values and httptest. ```go // import "net/url" q := make(url.Values) q.Set("email", "jon@labstack.com") req := httptest.NewRequest(http.MethodGet, "/?"+q.Encode(), nil) ``` -------------------------------- ### Pretty-Printed XML Output Example Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/response.md This is an example of how pretty-printed XML will be formatted. ```xml Jon jon@labstack.com ``` -------------------------------- ### Import Echo v5 in Go Code Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/installation.md Example of how to import the Echo v5 package into your Go source files. ```go import "github.com/labstack/echo/v5" ``` -------------------------------- ### Client: Create User Request Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/crud.md Example of how to create a new user using a POST request with a JSON payload. ```sh curl -X POST \ -H 'Content-Type: application/json' \ -d '{"name":"Joe Smith"}' \ localhost:1323/users ``` -------------------------------- ### Subdomain Routing Server Example Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/subdomain.md Sets up multiple Echo instances for different subdomains (API, Blog, Website) and combines them using echo.NewVirtualHostHandler to dispatch requests based on the host name. Each subdomain has its own routes and middleware. ```go package main import ( "context" "net/http" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { // Hosts vHosts := make(map[string]*echo.Echo) //----- // API //----- api := echo.New() api.Use(middleware.RequestLogger()) api.Use(middleware.Recover()) vHosts["api.localhost:1323"] = api api.GET("/", func(c *echo.Context) error { return c.String(http.StatusOK, "API") }) //------ // Blog //------ blog := echo.New() blog.Use(middleware.RequestLogger()) blog.Use(middleware.Recover()) vHosts["blog.localhost:1323"] = blog blog.GET("/", func(c *echo.Context) error { return c.String(http.StatusOK, "Blog") }) //--------- // Website //--------- site := echo.New() site.Use(middleware.RequestLogger()) site.Use(middleware.Recover()) vHosts["localhost:1323"] = site site.GET("/", func(c *echo.Context) error { return c.String(http.StatusOK, "Website") }) e := echo.NewVirtualHostHandler(vHosts) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Serve Static Files with Echo#Static() Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Register a route to serve static files from a specified directory under a given path prefix. This example serves files from 'assets' under the '/static' path. ```go e := echo.New() e.Static("/static", "assets") ``` -------------------------------- ### Serve a Single Static File with Echo#File() Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Register a route to serve a single static file. This example serves 'public/index.html' from the root path. ```go e.File("/", "public/index.html") ``` -------------------------------- ### Run Echo Application Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/index.mdx Run your Go application using the 'go run' command. This command starts the Echo server, making it accessible. ```go go run main.go ⇨ :1323 ``` -------------------------------- ### Check Go Version Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/installation.md Verify that your Go installation meets the minimum requirement of Go 1.25 or newer. ```bash go version ``` -------------------------------- ### Start Multiple Echo Servers Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/load-balancing.md Command to start two Echo server instances on different ports, intended for load balancing. ```sh cd upstream go run server.go server1 :8081 go run server.go server2 :8082 ``` -------------------------------- ### Download File Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/file-download.md Serve a file for download using the browser's default content disposition. This example sets up routes to serve 'index.html' and 'echo.svg'. ```go package main import ( "context" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.GET("/", func(c *echo.Context) error { return c.File("index.html") }) e.GET("/file", func(c *echo.Context) error { return c.File("echo.svg") }) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Example Log Entry with Request ID Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/request-id.md An example log entry showing the 'id' field populated with the Request ID '3', demonstrating how the middleware affects logging. ```json {"time":"2017-11-13T20:26:28.6438003+01:00","id":"3","remote_ip":"::1","host":"localhost:1323","method":"GET","uri":"/?my=param","my":"param","status":200, "latency":0,"latency_human":"0s","bytes_in":0,"bytes_out":13} ``` -------------------------------- ### Testing with echotest.ContextConfig Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/testing.md Uses echotest.ContextConfig to declaratively build a context and recorder for testing the createUser handler, simplifying setup. ```go // Same test as above, using echotest. func TestCreateUserWithEchoTest(t *testing.T) { c, rec := echotest.ContextConfig{ Headers: map[string][]string{ echo.HeaderContentType: {echo.MIMEApplicationJSON}, }, JSONBody: []byte(userJSON), }.ToContextRecorder(t) h := &handler{mockDB} // Assertions if assert.NoError(t, h.createUser(c)) { assert.Equal(t, http.StatusCreated, rec.Code) assert.Equal(t, userJSON+"\n", rec.Body.String()) } } ``` -------------------------------- ### Client-Side Request Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/streaming-response.md This command-line example shows how to fetch the streamed JSON response from the server. It's a simple way to test the streaming functionality. ```sh curl localhost:1323 ``` -------------------------------- ### Initialize and Use Session Middleware Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md Initializes a cookie-based session store and applies the session middleware to the Echo instance. This setup is required before using session-related endpoints. ```go sessionStore := sessions.NewCookieStore([]byte("secret")) e.Use(NewSessionMiddleware(sessionStore)) ``` -------------------------------- ### Request Logging with Zerolog Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/logger.md Configure the request logger to use Zerolog for efficient, structured logging. This example logs the request URI and status code. ```go logger := zerolog.New(os.Stdout) e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ LogURI: true, LogStatus: true, LogValuesFunc: func(c *echo.Context, v middleware.RequestLoggerValues) error { logger.Info(). Str("URI", v.URI). Int("status", v.Status). Msg("request") return nil }, })) ``` -------------------------------- ### Multiple Sources & Precedence Example Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/binding.md A field can declare several sources. Data is bound in order: Path parameters, Query parameters (GET/DELETE only), Request body. Each step overwrites the previous. ```go type User struct { ID string `param:"id" query:"id" form:"id" json:"id" xml:"id"` } ``` -------------------------------- ### Download File Inline Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/file-download.md Serve a file to be displayed inline by the browser using `c.Inline`. This example serves 'inline.txt' with a 'Content-Disposition: inline' header. ```go package main import ( "context" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.GET("/", func(c *echo.Context) error { return c.File("index.html") }) e.GET("/inline", func(c *echo.Context) error { return c.Inline("inline.txt", "inline.txt") }) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Download File Attachment Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/file-download.md Serve a file as an attachment using `c.Attachment`, prompting the browser to download it with a specified filename. This example serves 'attachment.txt' as 'attachment.txt'. ```go package main import ( "context" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.GET("/", func(c *echo.Context) error { return c.File("index.html") }) e.GET("/attachment", func(c *echo.Context) error { return c.Attachment("attachment.txt", "attachment.txt") }) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Configure Recover Middleware Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/recover.md Customize the Recover middleware's behavior, such as setting the stack size, by providing a configuration object. This example sets the stack size to 1 KB. ```go e.Use(middleware.RecoverWithConfig(middleware.RecoverConfig{ StackSize: 1 << 10, // 1 KB })) ``` -------------------------------- ### Set Default Filesystem Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Change the root directory for static files by setting the Echo#Filesystem field. This example sets the root to the 'assets' directory. ```go e := echo.New() e.Filesystem = os.DirFS("assets") ``` -------------------------------- ### Serve Static Files from embed.FS with Echo#StaticFS() Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Serve static files from an embedded filesystem, such as embed.FS. Use echo.MustSubFS to ensure files are rooted correctly within the subdirectory. This example serves files from the 'assets/images' subdirectory. ```go //go:embed "assets/images" var images embed.FS func main() { e := echo.New() e.StaticFS("/images", echo.MustSubFS(images, "assets/images")) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Serve a Favicon with Echo#File() Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/static-files.md Serve a specific static file, like a favicon, using Echo#File(). Note that the file path should be relative and not start with a leading slash when using most fs.FS implementations. ```go e := echo.New() e.Filesystem = os.DirFS("/") e.File("/favicon.ico", "app/assets/favicon.ico") // The file path must not have a leading slash. ``` -------------------------------- ### Initialize New Project and Add Echo v5 Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/installation.md Steps to create a new Go module, initialize it, and then add the Echo v5 module. ```bash mkdir myapp && cd myapp go mod init myapp go get github.com/labstack/echo/v5 ``` -------------------------------- ### Graceful Shutdown with Custom HTTP Server Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/graceful-shutdown.md This snippet shows how to manage a custom `http.Server` for graceful shutdown. It starts the server in a goroutine, waits for an interrupt signal, and then calls `Shutdown` with a timeout. ```go func mainWithHTTPServer() { // Setup e := echo.New() e.GET("/", func(c *echo.Context) error { time.Sleep(5 * time.Second) return c.JSON(http.StatusOK, "OK") }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() s := http.Server{Addr: ":1323", Handler: e} // Start server go func() { if err := s.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { e.Logger.Error("failed to start server", "error", err) } }() // Wait for interrupt signal to gracefully shut down the server with a timeout of 10 seconds. <- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := s.Shutdown(ctx); err != nil { e.Logger.Error("failed to stop server", "error", err) } } ``` -------------------------------- ### Complete Server Implementation Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2-server-push.md A full Go program demonstrating HTTP/2 Server Push with Echox. It includes static file serving, route handling for index.html with dependency pushing, and TLS server startup. ```go package main import ( "context" "net/http" "github.com/labstack/echo/v5" ) func main() { e := echo.New() e.Static("/", "static") e.GET("/", func(c *echo.Context) (err error) { rw, err := echo.UnwrapResponse(c.Response()) if err != nil { return } if pusher, ok := rw.ResponseWriter.(http.Pusher); ok { if err = pusher.Push("/app.css", nil); err != nil { return } if err = pusher.Push("/app.js", nil); err != nil { return } if err = pusher.Push("/echo.png", nil); err != nil { return } } return c.File("index.html") }) sc := echo.StartConfig{Address: ":1323"} if err := sc.StartTLS(context.Background(), e, "cert.pem", "key.pem"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### JWT Response Example Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/jwt.md This is an example of the JSON response received after a successful login, containing the JWT. ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY" } ``` -------------------------------- ### Echo Server Implementation Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/load-balancing.md Sets up an Echo server that responds with its name and port. This server is intended to be run multiple times for load balancing. ```go package main import ( "context" "fmt" "net/http" "os" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) var index = ` Upstream Server

Hello from upstream server %s

` func main() { name := os.Args[1] port := os.Args[2] e := echo.New() e.Use(middleware.Recover()) e.Use(middleware.RequestLogger()) e.GET("/", func(c *echo.Context) error { return c.HTML(http.StatusOK, fmt.Sprintf(index, name)) }) sc := echo.StartConfig{Address: port} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Get Session from Context Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md Retrieves the session store from the context and then gets a specific session by name. Handles potential errors during store retrieval. ```go func GetSession(c *echo.Context, name string) (*sessions.Session, error) { store, err := echo.ContextGet[sessions.Store](c, "_session_store") if err != nil { return nil, err } return store.Get(c.Request(), name) } ``` -------------------------------- ### Setting Path Parameters Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/testing.md Demonstrates how to set path parameters on an Echo context using c.SetPathValues. ```go c.SetPathValues(echo.PathValues{ {Name: "id", Value: "1"}, {Name: "email", Value: "jon@labstack.com"}, }) ``` -------------------------------- ### Static File Serving with Custom Configuration Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/static.md Serve static files from the 'static' directory and enable directory browsing. ```go e := echo.New() e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ Root: "static", Browse: true, })) ``` -------------------------------- ### Advanced Template Example with Echo Reverse Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/templates.md This example demonstrates how to call Echo's Reverse function from within an HTML template. It requires a custom renderer that augments the context passed to the template. ```html

Hello {{index . "name"}}

{{ with $x := index . "reverse" }} {{ call $x "foobar" }} {{ end }}

``` -------------------------------- ### Restricted Resource Response Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/jwt.md Example response from a restricted resource after successful authentication with a valid JWT. ```text Welcome Jon Snow! ``` -------------------------------- ### Client: Delete User Request Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/crud.md Example of how to delete a user by their ID using a DELETE request. ```sh curl -X DELETE localhost:1323/users/1 ``` -------------------------------- ### Proxy with Custom Configuration Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/proxy.md Initialize the Proxy middleware with a custom configuration, allowing for fine-grained control over its behavior. ```go e := echo.New() e.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{})) ``` -------------------------------- ### Basic Static File Serving Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/static.md Serve static files from the '/static' directory. Requests to '/js/main.js' will fetch 'static/js/main.js'. ```go e := echo.New() e.Use(middleware.Static("/static")) ``` -------------------------------- ### Custom Method Override Configuration Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/method-override.md Configure Method Override to get the overridden method from a form field named '_method'. ```go e.Pre(middleware.MethodOverrideWithConfig(middleware.MethodOverrideConfig{ Getter: middleware.MethodFromForm("_method"), })) ``` -------------------------------- ### Client: Update User Request Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/crud.md Example of how to update an existing user's name using a PUT request with a JSON payload. ```sh curl -X PUT \ -H 'Content-Type: application/json' \ -d '{"name":"Joe"}' \ localhost:1323/users/1 ``` -------------------------------- ### Testing GetUser Handler with echotest Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/testing.md Tests the getUser handler using echotest.ContextConfig to set path parameters and simulate a GET request. ```go func TestGetUser(t *testing.T) { c, rec := echotest.ContextConfig{ PathValues: echo.PathValues{ {Name: "email", Value: "jon@labstack.com"}, }, Headers: map[string][]string{ echo.HeaderContentType: {echo.MIMEApplicationJSON}, }, }.ToContextRecorder(t) h := &handler{mockDB} // Assertions if assert.NoError(t, h.getUser(c)) { assert.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, userJSON+"\n", rec.Body.String()) } } ``` -------------------------------- ### Handling Files in Responses Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/context.md Serve files directly, prompt for download with a specified filename, or render files inline. ```go c.File("public/report.pdf") // serve a file c.Attachment("invoice.pdf", "inv.pdf") // prompt download c.Inline("photo.png", "photo.png") // render inline ``` -------------------------------- ### Sample Prometheus Metrics Output Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/prometheus.md Example output of Prometheus metrics collected by the middleware, showing request duration, size, and total requests. ```bash curl http://localhost:8080/metrics # HELP echo_request_duration_seconds The HTTP request latencies in seconds. # TYPE echo_request_duration_seconds summary echo_request_duration_seconds_sum 0.41086482 echo_request_duration_seconds_count 1 # HELP echo_request_size_bytes The HTTP request sizes in bytes. # TYPE echo_request_size_bytes summary echo_request_size_bytes_sum 56 echo_request_size_bytes_count 1 # HELP echo_requests_total How many HTTP requests processed, partitioned by status code and HTTP method. # TYPE echo_requests_total counter echo_requests_total{code="200",host="localhost:8080",method="GET",url="/"} 1 # HELP echo_response_size_bytes The HTTP response sizes in bytes. # TYPE echo_response_size_bytes summary echo_response_size_bytes_sum 61 echo_response_size_bytes_count 1 ... ``` -------------------------------- ### Serve HTML and Push Dependencies Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2-server-push.md Serves an index.html file and proactively pushes its associated assets (CSS, JS, images) if the underlying response writer supports http.Pusher. This eliminates a round trip for these assets. ```go e.GET("/", func(c *echo.Context) (err error) { rw, err := echo.UnwrapResponse(c.Response()) if err != nil { return } if pusher, ok := rw.ResponseWriter.(http.Pusher); ok { if err = pusher.Push("/app.css", nil); err != nil { return } if err = pusher.Push("/app.js", nil); err != nil { return } if err = pusher.Push("/echo.png", nil); err != nil { return } } return c.File("index.html") }) ``` -------------------------------- ### Registering Routes for Any or Multiple Methods Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/routing.md Use `Any` to register a handler for all supported HTTP methods on a path, or `Match` to specify a subset of methods. ```go e.Any("/ping", pong) e.Match([]string{http.MethodGet, http.MethodPost}, "/form", handleForm) ``` -------------------------------- ### Import Gorilla Sessions Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md Import the necessary sessions package for session management. ```go import ( "github.com/gorilla/sessions" ) ``` -------------------------------- ### Pre-compile Templates with ParseGlob Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/templates.md Pre-compile your HTML templates using ParseGlob to efficiently load all templates from a specified directory. This is typically done once during application setup. ```html {{define "hello"}}Hello, {{.}}{{end}} ``` ```go t := &Template{ templates: template.Must(template.ParseGlob("public/views/*.html")) } ``` -------------------------------- ### Graceful Shutdown with Echo StartConfig Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/graceful-shutdown.md This snippet demonstrates how to use `echo.StartConfig` with a cancellable context and `GracefulTimeout` for automatic graceful shutdown on interrupt signals. ```go package main import ( "context" "errors" "net/http" "os" "os/signal" "syscall" "time" "github.com/labstack/echo/v5" ) func main() { // Setup e := echo.New() e.GET("/", func(c *echo.Context) error { time.Sleep(5 * time.Second) return c.JSON(http.StatusOK, "OK") }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() sc := echo.StartConfig{ Address: ":1323", GracefulTimeout: 5 * time.Second, } if err := sc.Start(ctx, e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### SSE Server Implementation Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/sse.md Sets up an Echo server to handle SSE connections. It writes SSE headers and emits events every second. Use http.NewResponseController(w).Flush() to push events immediately. Ensure server.WriteTimeout is disabled for SSE. ```go package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.File("/", "./index.html") e.GET("/sse", func(c *echo.Context) error { log.Printf("SSE client connected, ip: %v", c.RealIP()) w := c.Response() w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() count := uint64(0) for { select { case <-c.Request().Context().Done(): log.Printf("SSE client disconnected, ip: %v", c.RealIP()) return nil case <-ticker.C: count++ event := Event{ Data: []byte(fmt.Sprintf("count: %d, time: %s\n\n", count, time.Now().Format(time.RFC3339Nano))), } if err := event.MarshalTo(w); err != nil { return err } if err := http.NewResponseController(w).Flush(); err != nil { return err } } } }) sc := echo.StartConfig{ Address: ":8080", BeforeServeFunc: func(s *http.Server) error { s.WriteTimeout = 0 // IMPORTANT: disable for SSE return nil }, } ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) // start shutdown process on ctrl+c defer cancel() if err := sc.Start(ctx, e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Configure CORS with an Allow List Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/cors.md Use `middleware.CORS` with a list of allowed origins to restrict access. This example allows requests from `https://labstack.com` and `https://labstack.net`. ```go package main import ( "context" "net/http" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" ) var ( users = []string{"Joe", "Veer", "Zion"} ) func getUsers(c *echo.Context) error { return c.JSON(http.StatusOK, users) } func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) // CORS default // Allows requests from any origin wth GET, HEAD, PUT, POST or DELETE method. // e.Use(middleware.CORS("*\n")) // CORS restricted // Allows requests from any `https://labstack.com` or `https://labstack.net` origin e.Use(middleware.CORS("https://labstack.com", "https://labstack.net")) e.GET("/api/users", getUsers) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Custom Rewrite Configuration Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/rewrite.md Initialize Echo and apply rewrite middleware with custom configuration. ```go e := echo.New() e.Pre(middleware.RewriteWithConfig(middleware.RewriteConfig{})) ``` -------------------------------- ### Request Logging with Logrus Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/logger.md Configure the request logger to use Logrus, a popular logging library with a customizable Hook API. This example logs the request URI and status. ```go log := logrus.New() e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{ LogURI: true, LogStatus: true, LogValuesFunc: func(c *echo.Context, values middleware.RequestLoggerValues) error { log.WithFields(logrus.Fields{ "URI": values.URI, "status": values.Status, }).Info("request") return nil }, })) ``` -------------------------------- ### Create Session Middleware Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md Creates the session middleware using a provided session store. The store is set in the context for later retrieval. ```go func NewSessionMiddleware(store sessions.Store) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { c.Set("_session_store", store) return next(c) } } } ``` -------------------------------- ### HTML Structure for Server Push Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/http2-server-push.md An example HTML file that links to CSS, JavaScript, and an image. These assets are intended to be pushed by the server using HTTP/2 Server Push. ```html HTTP/2 Server Push

The following static files are served via HTTP/2 server push

``` -------------------------------- ### Serve WebSocket with net/websocket Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/websocket.md This Go server code uses the standard golang.org/x/net/websocket package to handle incoming WebSocket connections. It continuously sends 'Hello, Client!' and reads messages from the client. ```go package main import ( "context" "fmt" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" "golang.org/x/net/websocket" ) func hello(c *echo.Context) error { websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() for { // Write if err := websocket.Message.Send(ws, "Hello, Client!"); err != nil { c.Logger().Error("failed to write WS message", "error", err) } // Read msg := "" if err := websocket.Message.Receive(ws, &msg); err != nil { c.Logger().Error("failed to write WS message", "error", err) } fmt.Printf("%s\n", msg) } }).ServeHTTP(c.Response(), c.Request()) return nil } func main() { e := echo.New() e.Use(middleware.RequestLogger()) e.Use(middleware.Recover()) e.Static("/", "../public") e.GET("/ws", hello) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Retrieve Path Parameter by Name Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/request.md Use `Context#Param(name string)` to get a string value from path parameters. For other types, use the generic `echo.PathParam[T]` function. ```go e.GET("/users/:name", func(c *echo.Context) error { name := c.Param("name") return c.String(http.StatusOK, name) }) ``` ```go id, err := echo.PathParam[int](c, "id") if err != nil { return err } ``` -------------------------------- ### Retrieve Query Parameter by Name Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/request.md Use `Context#QueryParam(name string)` to get a string value from query parameters. For other types, use the generic `echo.QueryParam[T]` function. ```go func(c *echo.Context) error { name := c.QueryParam("name") return c.String(http.StatusOK, name) } ``` ```go age, err := echo.QueryParam[int](c, "age") if err != nil { return err } ``` -------------------------------- ### Retrieve Form Field by Name Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/guide/request.md Use `Context#FormValue(name string)` to get a string value from form data. For other types, use the generic `echo.FormValue[T]` function. ```go e.POST("/form", func(c *echo.Context) error { name := c.FormValue("name") return c.String(http.StatusOK, name) }) ``` ```go age, err := echo.FormValue[int](c, "age") if err != nil { return err } ``` -------------------------------- ### Embed and Serve Static Assets with Echo Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/cookbook/embed-resources.md This Go code embeds static assets into the binary using `embed.FS` and serves them via Echo. It supports a live mode to read from disk during development. ```go package main import ( "context" "embed" "io/fs" "log" "net/http" "os" "github.com/labstack/echo/v5" ) //go:embed app var embededFiles embed.FS func getFileSystem(useOS bool) http.FileSystem { if useOS { log.Print("using live mode") return http.FS(os.DirFS("app")) } log.Print("using embed mode") fsys, err := fs.Sub(embededFiles, "app") if err != nil { panic(err) } return http.FS(fsys) } func main() { e := echo.New() useOS := len(os.Args) > 1 && os.Args[1] == "live" assetHandler := http.FileServer(getFileSystem(useOS)) e.GET("/", echo.WrapHandler(assetHandler)) e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler))) sc := echo.StartConfig{Address: ":1323"} if err := sc.Start(context.Background(), e); err != nil { e.Logger.Error("failed to start server", "error", err) } } ``` -------------------------------- ### Full Echo Application with Session Management Source: https://github.com/labstack/echox/blob/master/site/src/content/docs/middleware/session.md A complete Echo application demonstrating session creation and reading. It includes endpoints for setting session values and retrieving them, along with error handling. ```go package main import ( "fmt" "net/http" "github.com/gorilla/sessions" "github.com/labstack/echo/v5" ) func NewSessionMiddleware(store sessions.Store) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c *echo.Context) error { c.Set("_session_store", store) return next(c) } } } func GetSession(c *echo.Context, name string) (*sessions.Session, error) { store, err := echo.ContextGet[sessions.Store](c, "_session_store") if err != nil { return nil, fmt.Errorf("failed to get session store: %w", err) } return store.Get(c.Request(), name) } func main() { e := echo.New() sessionStore := sessions.NewCookieStore([]byte("secret")) e.Use(NewSessionMiddleware(sessionStore)) e.GET("/create-session", func(c *echo.Context) error { sess, err := GetSession(c, "session") if err != nil { return err } sess.Options = &sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, } sess.Values["foo"] = "bar" if err := sess.Save(c.Request(), c.Response()); err != nil { return err } return c.NoContent(http.StatusOK) }) e.GET("/read-session", func(c *echo.Context) error { sess, err := GetSession(c, "session") if err != nil { return err } return c.String(http.StatusOK, fmt.Sprintf("foo=%v\n", sess.Values["foo"])) }) if err := e.Start(":8080"); err != nil { e.Logger.Error("failed to start server", "error", err) } } ```