echo package - github.com/labstack/echo/v5 - Go Packages

Package echo implements high performance, minimalist Go web framework.

Example:

package main

import (
	"log/slog"
	"net/http"

	"github.com/labstack/echo/v5"
	"github.com/labstack/echo/v5/middleware"
)

// Handler
func hello(c *echo.Context) error {
	return c.String(http.StatusOK, "Hello, World!")
}

func main() {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.RequestLogger())
	e.Use(middleware.Recover())

	// Routes
	e.GET("/", hello)

	// Start server
	if err := e.Start(":8080"); err != nil {
		slog.Error("failed to start server", "error", err)
	}
}

Learn more at https://echo.labstack.com

View Source

const (
	TimeLayoutUnixTime      = TimeLayout("UnixTime")      
	TimeLayoutUnixTimeMilli = TimeLayout("UnixTimeMilli") 
	TimeLayoutUnixTimeNano  = TimeLayout("UnixTimeNano")  
)

TimeLayout constants for parsing Unix timestamps in different precisions.

View Source

const (
	
	MIMEApplicationJSON = "application/json"
	
	
	
	
	MIMEApplicationJSONCharsetUTF8       = MIMEApplicationJSON + "; " + charsetUTF8
	MIMEApplicationJavaScript            = "application/javascript"
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + charsetUTF8
	MIMEApplicationXML                   = "application/xml"
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + charsetUTF8
	MIMETextXML                          = "text/xml"
	MIMETextXMLCharsetUTF8               = MIMETextXML + "; " + charsetUTF8
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
	MIMEApplicationProtobuf              = "application/protobuf"
	MIMEApplicationMsgpack               = "application/msgpack"
	MIMETextHTML                         = "text/html"
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + charsetUTF8
	MIMETextPlain                        = "text/plain"
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + charsetUTF8
	MIMEMultipartForm                    = "multipart/form-data"
	MIMEOctetStream                      = "application/octet-stream"
)

MIME types

View Source

const (

	
	PROPFIND = "PROPFIND"
	
	REPORT = "REPORT"
	
	RouteNotFound = "echo_route_not_found"
	
	
	RouteAny = "echo_route_any"
)

View Source

const (
	
	
	
	
	HeaderContentDisposition  = "Content-Disposition"
	HeaderContentEncoding     = "Content-Encoding"
	HeaderContentLength       = "Content-Length"
	HeaderContentType         = "Content-Type"

	
	

	

	
	HeaderXContentTypeOptions             = "X-Content-Type-Options"
	HeaderContentSecurityPolicy           = "Content-Security-Policy"
	HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"

	
	
	HeaderSecFetchSite = "Sec-Fetch-Site"
)

Headers

View Source

const (
	
	NotFoundRouteName = "echo_route_not_found_name"
	
	MethodNotAllowedRouteName = "echo_route_method_not_allowed_name"
)

View Source

const (
	
	
	ContextKeyHeaderAllow = "echo_header_allow"
)

Following errors can produce HTTP status code by implementing HTTPStatusCoder interface

View Source

var (
	ErrValidatorNotRegistered = errors.New("validator not registered")
	ErrRendererNotRegistered  = errors.New("renderer not registered")
	ErrInvalidRedirectCode    = errors.New("invalid redirect status code")
	ErrCookieNotFound         = errors.New("cookie not found")
	ErrInvalidCertOrKeyType   = errors.New("invalid cert or key type, must be string or []byte")
	ErrInvalidListenerNetwork = errors.New("invalid listener network")
)

Following errors fall into 500 (InternalServerError) category

ErrInvalidKeyType is error that is returned when the value is not castable to expected type.

ErrNonExistentKey is error that is returned when key does not exist

BindHeaders binds HTTP headers to a bindable object

BindPathValues binds path parameter values to bindable object

BindQueryParams binds query params to bindable object

ContextGet retrieves a value from the context store or ErrNonExistentKey error the key is missing. Returns ErrInvalidKeyType error if the value is not castable to type T.

ContextGetOr retrieves a value from the context store or returns a default value when the key is missing. Returns ErrInvalidKeyType error if the value is not castable to type T.

FormValue extracts and parses a single form value from the request by key. It returns the typed value and an error if binding fails. Returns ErrNonExistentKey if parameter not found.

Empty String Handling:

If the form field exists but has an empty value, the zero value of type T is returned
with no error. For example, an empty form field returns (0, nil) for int types.
This differs from standard library behavior where parsing empty strings returns errors.
To treat empty values as errors, validate the result separately or check the raw value.

See ParseValue for supported types and options

FormValueOr extracts and parses a single form value from the request by key. Returns defaultValue if the parameter is not found or has an empty value. Returns an error only if parsing fails or form parsing errors occur.

Example:

limit, err := echo.FormValueOr[int](c, "limit", 100)
// If "limit" is missing: returns (100, nil)
// If "limit" is "50": returns (50, nil)
// If "limit" is "abc": returns (100, BindingError)

See ParseValue for supported types and options

FormValues extracts and parses all values for a form values key as a slice. It returns the typed slice and an error if binding any value fails. Returns ErrNonExistentKey if parameter not found.

See ParseValues for supported types and options

FormValuesOr extracts and parses all values for a form values key as a slice. Returns defaultValue if the parameter is not found. Returns an error only if parsing any value fails or form parsing errors occur.

Example:

tags, err := echo.FormValuesOr[string](c, "tags", []string{})
// If "tags" is missing: returns ([], nil)
// If form parsing fails: returns (nil, error)

See ParseValues for supported types and options

func HandlerName

HandlerName returns string name for given function.

MustSubFS creates sub FS from current filesystem or panic on failure. Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.

MustSubFS is helpful when dealing with `embed.FS` because for example `//go:embed assets/images` embeds files with paths including `assets/images` as their prefix. In that case use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary prefix for directory path.

NewBindingError creates new instance of binding error

ParseValue parses value to generic type

Types that are supported:

  • bool
  • float32
  • float64
  • int
  • int8
  • int16
  • int32
  • int64
  • uint
  • uint8/byte
  • uint16
  • uint32
  • uint64
  • string
  • echo.BindUnmarshaler interface
  • encoding.TextUnmarshaler interface
  • json.Unmarshaler interface
  • time.Duration
  • time.Time use echo.TimeOpts or echo.TimeLayout to set time parsing configuration

ParseValueOr parses value to generic type, when value is empty defaultValue is returned.

Types that are supported:

  • bool
  • float32
  • float64
  • int
  • int8
  • int16
  • int32
  • int64
  • uint
  • uint8/byte
  • uint16
  • uint32
  • uint64
  • string
  • echo.BindUnmarshaler interface
  • encoding.TextUnmarshaler interface
  • json.Unmarshaler interface
  • time.Duration
  • time.Time use echo.TimeOpts or echo.TimeLayout to set time parsing configuration

ParseValues parses value to generic type slice. Same types are supported as ParseValue function but the result type is slice instead of scalar value.

See ParseValue for supported types and options

func ParseValuesOr[T any](values []string, defaultValue []T, opts ...any) ([]T, error)

ParseValuesOr parses value to generic type slice, when value is empty defaultValue is returned. Same types are supported as ParseValue function but the result type is slice instead of scalar value.

See ParseValue for supported types and options

PathParam extracts and parses a path parameter from the context by name. It returns the typed value and an error if binding fails. Returns ErrNonExistentKey if parameter not found.

Empty String Handling:

If the parameter exists but has an empty value, the zero value of type T is returned
with no error. For example, a path parameter with value "" returns (0, nil) for int types.
This differs from standard library behavior where parsing empty strings returns errors.
To treat empty values as errors, validate the result separately or check the raw value.

See ParseValue for supported types and options

PathParamOr extracts and parses a path parameter from the context by name. Returns defaultValue if the parameter is not found or has an empty value. Returns an error only if parsing fails (e.g., "abc" for int type).

Example:

id, err := echo.PathParamOr[int](c, "id", 0)
// If "id" is missing: returns (0, nil)
// If "id" is "123": returns (123, nil)
// If "id" is "abc": returns (0, BindingError)

See ParseValue for supported types and options

QueryParam extracts and parses a single query parameter from the request by key. It returns the typed value and an error if binding fails. Returns ErrNonExistentKey if parameter not found.

Empty String Handling:

If the parameter exists but has an empty value (?key=), the zero value of type T is returned
with no error. For example, "?count=" returns (0, nil) for int types.
This differs from standard library behavior where parsing empty strings returns errors.
To treat empty values as errors, validate the result separately or check the raw value.

Behavior Summary:

  • Missing key (?other=value): returns (zero, ErrNonExistentKey)
  • Empty value (?key=): returns (zero, nil)
  • Invalid value (?key=abc for int): returns (zero, BindingError)

See ParseValue for supported types and options

QueryParamOr extracts and parses a single query parameter from the request by key. Returns defaultValue if the parameter is not found or has an empty value. Returns an error only if parsing fails (e.g., "abc" for int type).

Example:

page, err := echo.QueryParamOr[int](c, "page", 1)
// If "page" is missing: returns (1, nil)
// If "page" is "5": returns (5, nil)
// If "page" is "abc": returns (1, BindingError)

See ParseValue for supported types and options

QueryParams extracts and parses all values for a query parameter key as a slice. It returns the typed slice and an error if binding any value fails. Returns ErrNonExistentKey if parameter not found.

See ParseValues for supported types and options

QueryParamsOr extracts and parses all values for a query parameter key as a slice. Returns defaultValue if the parameter is not found. Returns an error only if parsing any value fails.

Example:

ids, err := echo.QueryParamsOr[int](c, "ids", []int{})
// If "ids" is missing: returns ([], nil)
// If "ids" is "1&ids=2": returns ([1, 2], nil)
// If "ids" contains "abc": returns ([], BindingError)

See ParseValues for supported types and options

StatusCode returns status code from error if it implements HTTPStatusCoder interface. If error does not implement the interface it returns 0.

AddRouteError is error returned by Router.Add containing information what actual route adding failed. Useful for mass adding (i.e. Any() routes)

type BindUnmarshaler interface {
	
	UnmarshalParam(param string) error
}

BindUnmarshaler is the interface used to wrap the UnmarshalParam method. Types that don't implement this, but do implement encoding.TextUnmarshaler will use that interface instead.

type Binder interface {
	Bind(c *Context, target any) error
}

Binder is the interface that wraps the Bind method.

type BindingError struct {
	
	Field string `json:"field"`
	*HTTPError
	
	Values []string `json:"-"`
}

BindingError represents an error that occurred while binding request data.

Error returns error message

type Config struct {
	
	
	Logger *slog.Logger

	
	
	
	HTTPErrorHandler HTTPErrorHandler

	
	
	
	Router Router

	
	
	
	OnAddRoute func(route Route) error

	
	
	
	Filesystem fs.FS

	
	
	
	Binder Binder

	
	
	
	Validator Validator

	
	
	
	Renderer Renderer

	
	
	
	JSONSerializer JSONSerializer

	
	
	
	IPExtractor IPExtractor

	
	
	FormParseMaxMemory int64
}

Config is configuration for NewWithConfig function

Context represents the context of the current HTTP request. It holds request and response objects, path, path parameters, data and registered handler.

NewContext returns a new Context instance.

Note: request,response and e can be left to nil as Echo.ServeHTTP will call c.Reset(req,resp) anyway these arguments are useful when creating context for tests and cases like that.

Attachment sends a response as attachment, prompting client to save the file.

Bind binds path params, query params and the request body into provided type `i`. The default binder binds body based on Content-Type header.

Blob sends a blob response with status code and content type.

Cookie returns the named cookie provided in the request.

Cookies returns the HTTP cookies sent with the request.

func (c *Context) Echo() *Echo

Echo returns the `Echo` instance.

File sends a response with the content of the file.

FileFS serves file from given file system.

When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths including `assets/images` as their prefix.

FormFile returns the multipart form file for the provided name.

FormValue returns the form field value for the provided name.

FormValueOr returns the form field value or default value for the provided name. Note: FormValueOr does not distinguish if form had no value by that name or value was empty string

FormValues returns the form field values as `url.Values`.

Get retrieves data from the context. Method returns any(nil) when key does not exist which is different from typed nil (eg. []byte(nil)).

HTML sends an HTTP response with status code.

HTMLBlob sends an HTTP blob response with status code.

func (c *Context) InitializeRoute(ri *RouteInfo, pathValues *PathValues)

InitializeRoute sets the route related variables of this request to the context.

Inline sends a response as inline, opening the file in the browser.

IsTLS returns true if HTTP connection is TLS otherwise false.

func (c *Context) IsWebSocket() bool

IsWebSocket returns true if HTTP connection is WebSocket otherwise false.

JSON sends a JSON response with status code.

JSONBlob sends a JSON blob response with status code.

JSONP sends a JSONP response with status code. It uses `callback` to construct the JSONP payload.

JSONPBlob sends a JSONP blob response with status code. It uses `callback` to construct the JSONP payload.

JSONPretty sends a pretty-print JSON with status code.

Logger returns logger in Context

MultipartForm returns the multipart form.

func (*Context) NoContent

NoContent sends a response with no body and a status code.

Param returns path parameter by name.

ParamOr returns the path parameter or default value for the provided name.

Notes for DefaultRouter implementation: Path parameter could be empty for cases like that: * route `/release-:version/bin` and request URL is `/release-/bin` * route `/api/:version/image.jpg` and request URL is `/api//image.jpg` but not when path parameter is last part of route path * route `/download/file.:ext` will not match request `/download/file.`

Path returns the registered path for the handler.

func (c *Context) PathValues() PathValues

PathValues returns path parameter values.

QueryParam returns the query param for the provided name.

QueryParamOr returns the query param or default value for the provided name. Note: QueryParamOr does not distinguish if query had no value by that name or value was empty string This means URLs `/test?search=` and `/test` would both return `1` for `c.QueryParamOr("search", "1")`

QueryParams returns the query parameters as `url.Values`.

QueryString returns the URL query string.

RealIP returns the client's network address based on `X-Forwarded-For` or `X-Real-IP` request header. The behavior can be configured using `Echo#IPExtractor`.

Redirect redirects the request to a provided URL with status code.

Render renders a template with data and sends a text/html response with status code. Renderer must be registered using `Echo.Renderer`.

Request returns `*http.Request`.

Reset resets the context after request completes. It must be called along with `Echo#AcquireContext()` and `Echo#ReleaseContext()`. See `Echo#ServeHTTP()`

Response returns `*Response`.

func (c *Context) RouteInfo() RouteInfo

RouteInfo returns current request route information. Method, Path, Name and params if they exist for matched route.

RouteInfo returns generic "empty" struct for these cases: * Context is accessed before Routing is done. For example inside Pre middlewares (`e.Pre()`) * Router did not find matching route - 404 (route not found) * Router did not find matching route with same method - 405 (method not allowed)

Scheme returns the HTTP protocol scheme, `http` or `https`.

Set saves data in the context.

SetCookie adds a `Set-Cookie` header in HTTP response.

SetLogger sets logger in Context

SetPath sets the registered path for the handler.

func (c *Context) SetPathValues(pathValues PathValues)

SetPathValues sets path parameters for current request.

SetRequest sets `*http.Request`.

SetResponse sets `*http.ResponseWriter`. Some context methods and/or middleware require that given ResponseWriter implements following method `Unwrap() http.ResponseWriter` which eventually should return *echo.Response instance.

Stream sends a streaming response with status code and content type.

String sends a string response with status code.

Validate validates provided `i`. It is usually called after `Context#Bind()`. Validator must be registered using `Echo#Validator`.

XML sends an XML response with status code.

XMLBlob sends an XML blob response with status code.

XMLPretty sends a pretty-print XML with status code.

type DefaultBinder struct{}

DefaultBinder is the default implementation of the Binder interface.

Bind implements the `Binder#Bind` function. Binding is done in following order: 1) path params; 2) query params; 3) request body. Each step COULD override previous step bound values. For single source binding use their own methods BindBody, BindQueryParams, BindPathValues.

type DefaultJSONSerializer struct{}

DefaultJSONSerializer implements JSON encoding using encoding/json.

Deserialize reads a JSON from a request body and converts it into an interface.

Serialize converts an interface into a json and writes it to the response. You can optionally use the indent parameter to produce pretty JSONs.

type DefaultRouter struct {
	
}

DefaultRouter is the registry of all registered routes for an `Echo` instance for request matching and URL path parameter parsing. Note: DefaultRouter is not coroutine-safe. Do not Add/Remove routes after HTTP server has been started with Echo.

func NewRouter(config RouterConfig) *DefaultRouter

NewRouter returns a new Router instance.

Add registers a new route for method and path with matching handler.

Remove unregisters registered route

func (r *DefaultRouter) Route(c *Context) HandlerFunc

Route looks up a handler registered for method and path. It also parses URL for path parameters and loads them into context.

For performance:

- Get context from `Echo#AcquireContext()` - Reset it `Context#Reset()` - Return it `Echo#ReleaseContext()`.

func (r *DefaultRouter) Routes() Routes

Routes returns all registered routes

type Echo struct {
	Binder           Binder
	Filesystem       fs.FS
	Renderer         Renderer
	Validator        Validator
	JSONSerializer   JSONSerializer
	OnAddRoute       func(route Route) error
	HTTPErrorHandler HTTPErrorHandler
	Logger           *slog.Logger
	
}

Echo is the top-level framework instance.

Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these fields from handlers/middlewares and changing field values at the same time leads to data-races. Same rule applies to adding new routes after server has been started - Adding a route is not Goroutine safe action.

New creates an instance of Echo.

func NewVirtualHostHandler

func NewVirtualHostHandler(vhosts map[string]*Echo) *Echo

NewVirtualHostHandler creates instance of Echo that routes requests to given virtual hosts when hosts in request does not exist in given map the request is served by returned Echo instance.

func NewWithConfig(config Config) *Echo

NewWithConfig creates an instance of Echo with given configuration.

func (e *Echo) AcquireContext() *Context

AcquireContext returns an empty `Context` instance from the pool. You must return the context by calling `ReleaseContext()`.

func (e *Echo) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo

Add registers a new route for an HTTP method and path with matching handler in the router with optional route-level middleware.

func (e *Echo) AddRoute(route Route) (RouteInfo, error)

AddRoute registers a new Route with default host Router

func (e *Echo) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo

Any registers a new route for all HTTP methods (supported by Echo) and path with matching handler in the router with optional route-level middleware.

Note: this method only adds specific set of supported HTTP methods as handler and is not true "catch-any-arbitrary-method" way of matching requests.

CONNECT registers a new CONNECT route for a path with matching handler in the router with optional route-level middleware. Panics on error.

DELETE registers a new DELETE route for a path with matching handler in the router with optional route-level middleware. Panics on error.

func (e *Echo) File(path, file string, middleware ...MiddlewareFunc) RouteInfo

File registers a new route with path to serve a static file with optional route-level middleware. Panics on error.

FileFS registers a new route with path to serve file from the provided file system.

GET registers a new GET route for a path with matching handler in the router with optional route-level middleware. Panics on error.

func (e *Echo) Group(prefix string, m ...MiddlewareFunc) (g *Group)

Group creates a new router group with prefix and optional group-level middleware.

HEAD registers a new HEAD route for a path with matching handler in the router with optional route-level middleware. Panics on error.

Match registers a new route for multiple HTTP methods and path with matching handler in the router with optional route-level middleware. Panics on error.

func (e *Echo) Middlewares() []MiddlewareFunc

Middlewares returns registered route level middlewares. Does not contain any group level middlewares. Use this method to build your own ServeHTTP method.

NOTE: returned slice is not a copy. Do not mutate.

NewContext returns a new Context instance.

Note: both request and response can be left to nil as Echo.ServeHTTP will call c.Reset(req,resp) anyway these arguments are useful when creating context for tests and cases like that.

OPTIONS registers a new OPTIONS route for a path with matching handler in the router with optional route-level middleware. Panics on error.

PATCH registers a new PATCH route for a path with matching handler in the router with optional route-level middleware. Panics on error.

POST registers a new POST route for a path with matching handler in the router with optional route-level middleware. Panics on error.

PUT registers a new PUT route for a path with matching handler in the router with optional route-level middleware. Panics on error.

func (e *Echo) Pre(middleware ...MiddlewareFunc)

Pre adds middleware to the chain which is run before router tries to find matching route. Meaning middleware is executed even for 404 (not found) cases.

func (e *Echo) PreMiddlewares() []MiddlewareFunc

PreMiddlewares returns registered pre middlewares. These are middleware to the chain which are run before router tries to find matching route. Use this method to build your own ServeHTTP method.

NOTE: returned slice is not a copy. Do not mutate.

func (e *Echo) ReleaseContext(c *Context)

ReleaseContext returns the `Context` instance back to the pool. You must call it after `AcquireContext()`.

func (e *Echo) RouteNotFound(path string, h HandlerFunc, m ...MiddlewareFunc) RouteInfo

RouteNotFound registers a special-case route which is executed when no other route is found (i.e. HTTP 404 cases) for current request URL. Path supports static and named/any parameters just like other http method is defined. Generally path is ended with wildcard/match-any character (`/*`, `/download/*` etc).

Example: `e.RouteNotFound("/*", func(c *echo.Context) error { return c.NoContent(http.StatusNotFound) })`

func (e *Echo) Router() Router

Router returns the default router.

ServeHTTP implements `http.Handler` interface, which serves HTTP requests.

Start stars HTTP server on given address with Echo as a handler serving requests. The server can be shutdown by sending os.Interrupt signal with `ctrl+c`. Method returns only errors that are not http.ErrServerClosed.

Note: this method is created for use in examples/demos and is deliberately simple without providing configuration options.

In need of customization use:

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
sc := echo.StartConfig{Address: ":8080"}
if err := sc.Start(ctx, e); err != nil && !errors.Is(err, http.ErrServerClosed) {
	slog.Error(err.Error())
}

// or standard library `http.Server`

s := http.Server{Addr: ":8080", Handler: e}
if err := s.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
	slog.Error(err.Error())
}
func (e *Echo) Static(pathPrefix, fsRoot string, middleware ...MiddlewareFunc) RouteInfo

Static registers a new route with path prefix to serve static files from the provided root directory.

func (e *Echo) StaticFS(pathPrefix string, filesystem fs.FS, middleware ...MiddlewareFunc) RouteInfo

StaticFS registers a new route with path prefix to serve static files from the provided file system.

When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths including `assets/images` as their prefix.

TRACE registers a new TRACE route for a path with matching handler in the router with optional route-level middleware. Panics on error.

func (e *Echo) Use(middleware ...MiddlewareFunc)

Use adds middleware to the chain which is run after router has found matching route and before route/request handler method is executed.

Group is a set of sub-routes for a specified route. It can be used for inner routes that share a common middleware or functionality that should be separate from the parent echo instance while still inheriting from it.

func (g *Group) Add(method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo

Add implements `Echo#Add()` for sub-routes within the Group. Panics on error.

func (g *Group) AddRoute(route Route) (RouteInfo, error)

AddRoute registers a new Routable with Router

func (g *Group) Any(path string, handler HandlerFunc, middleware ...MiddlewareFunc) RouteInfo

Any implements `Echo#Any()` for sub-routes within the Group. Panics on error.

CONNECT implements `Echo#CONNECT()` for sub-routes within the Group. Panics on error.

DELETE implements `Echo#DELETE()` for sub-routes within the Group. Panics on error.

func (g *Group) File(path, file string, middleware ...MiddlewareFunc) RouteInfo

File implements `Echo#File()` for sub-routes within the Group. Panics on error.

FileFS implements `Echo#FileFS()` for sub-routes within the Group.

GET implements `Echo#GET()` for sub-routes within the Group. Panics on error.

func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group)

Group creates a new sub-group with prefix and optional sub-group-level middleware. Important! Group middlewares are only executed in case there was exact route match and not for 404 (not found) or 405 (method not allowed) cases. If this kind of behaviour is needed then add a catch-all route `/*` for the group which handler returns always 404

HEAD implements `Echo#HEAD()` for sub-routes within the Group. Panics on error.

Match implements `Echo#Match()` for sub-routes within the Group. Panics on error.

OPTIONS implements `Echo#OPTIONS()` for sub-routes within the Group. Panics on error.

PATCH implements `Echo#PATCH()` for sub-routes within the Group. Panics on error.

POST implements `Echo#POST()` for sub-routes within the Group. Panics on error.

PUT implements `Echo#PUT()` for sub-routes within the Group. Panics on error.

RouteNotFound implements `Echo#RouteNotFound()` for sub-routes within the Group.

Example: `g.RouteNotFound("/*", func(c *echo.Context) error { return c.NoContent(http.StatusNotFound) })`

func (g *Group) Static(pathPrefix, fsRoot string, middleware ...MiddlewareFunc) RouteInfo

Static implements `Echo#Static()` for sub-routes within the Group.

func (g *Group) StaticFS(pathPrefix string, filesystem fs.FS, middleware ...MiddlewareFunc) RouteInfo

StaticFS implements `Echo#StaticFS()` for sub-routes within the Group.

When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths including `assets/images` as their prefix.

TRACE implements `Echo#TRACE()` for sub-routes within the Group. Panics on error.

func (g *Group) Use(middleware ...MiddlewareFunc)

Use implements `Echo#Use()` for sub-routes within the Group. Group middlewares are not executed on request when there is no matching route found.

type HTTPError struct {
	
	Code    int    `json:"-"`
	Message string `json:"message"`
	
}

HTTPError represents an error that occurred while handling a request.

NewHTTPError creates new instance of HTTPError

Error makes it compatible with `error` interface.

func (he *HTTPError) StatusCode() int

StatusCode returns status code for HTTP response

Wrap eturns new HTTPError with given errors wrapped inside

type HTTPErrorHandler

type HTTPErrorHandler func(c *Context, err error)

HTTPErrorHandler is a centralized HTTP error handler.

func DefaultHTTPErrorHandler

func DefaultHTTPErrorHandler(exposeError bool) HTTPErrorHandler

DefaultHTTPErrorHandler creates new default HTTP error handler implementation. It sends a JSON response with status code. `exposeError` parameter decides if returned message will contain also error message or not

Note: DefaultHTTPErrorHandler does not log errors. Use middleware for it if errors need to be logged (separately) Note: In case errors happens in middleware call-chain that is returning from handler (which did not return an error). When handler has already sent response (ala c.JSON()) and there is error in middleware that is returning from handler. Then the error that global error handler received will be ignored because we have already "committed" the response and status code header has been sent to the client.

// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors

// run tests as external package to get real feel for API
package main

import (
	"encoding/json"
	"fmt"
	"github.com/labstack/echo/v5"
	"net/http"
	"net/http/httptest"
)

func main() {
	e := echo.New()
	e.GET("/api/endpoint", func(c *echo.Context) error {
		return &apiError{
			Code: http.StatusBadRequest,
			Body: map[string]any{"message": "custom error"},
		}
	})

	req := httptest.NewRequest(http.MethodGet, "/api/endpoint?err=1", nil)
	resp := httptest.NewRecorder()

	e.ServeHTTP(resp, req)

	fmt.Printf("%d %s", resp.Code, resp.Body.String())

}

type apiError struct {
	Code int
	Body any
}

func (e *apiError) StatusCode() int {
	return e.Code
}

func (e *apiError) MarshalJSON() ([]byte, error) {
	type body struct {
		Error any `json:"error"`
	}
	return json.Marshal(body{Error: e.Body})
}

func (e *apiError) Error() string {
	return http.StatusText(e.Code)
}
Output:

400 {"error":{"message":"custom error"}}
type HTTPStatusCoder interface {
	StatusCode() int
}

HTTPStatusCoder is interface that errors can implement to produce status code for HTTP response

type HandlerFunc

type HandlerFunc func(c *Context) error

HandlerFunc defines a function to serve HTTP requests.

func StaticDirectoryHandler

func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc

StaticDirectoryHandler creates handler function to serve files from provided file system When disablePathUnescaping is set then file name from path is not unescaped and is served as is.

func StaticFileHandler

StaticFileHandler creates handler function to serve file from provided file system

func WrapHandler

WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.

IPExtractor is a function to extract IP addr from http.Request. Set appropriate one to Echo#IPExtractor. See https://echo.labstack.com/guide/ip-address for more details.

func ExtractIPDirect() IPExtractor

ExtractIPDirect extracts IP address using actual IP address. Use this if your server faces to internet directory (i.e.: uses no proxy).

func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor

ExtractIPFromRealIPHeader extracts IP address using x-real-ip header. Use this if you put proxy which uses this header.

func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor

ExtractIPFromXFFHeader extracts IP address using x-forwarded-for header. Use this if you put proxy which uses this header. This returns nearest untrustable IP. If all IPs are trustable, returns furthest one (i.e.: XFF[0]).

JSONSerializer is the interface that encodes and decodes JSON to and from interfaces.

type MiddlewareConfigurator interface {
	ToMiddleware() (MiddlewareFunc, error)
}

MiddlewareConfigurator defines interface for creating middleware handlers with possibility to return configuration errors instead of panicking.

type MiddlewareFunc func(next HandlerFunc) HandlerFunc

MiddlewareFunc defines a function to process middleware.

WrapMiddleware wraps `func(http.Handler) http.Handler` into `echo.MiddlewareFunc`

PathValue is tuple pf path parameter name and its value in request path

type PathValues []PathValue

PathValues is collections of PathValue instances with various helper methods

Get returns path parameter value for given name or false.

GetOr returns path parameter value for given name or default value if the name does not exist.

Renderer is the interface that wraps the Render function.

Response wraps an http.ResponseWriter and implements its interface to be used by an HTTP handler to construct an HTTP response. See: https://golang.org/pkg/net/http/#ResponseWriter

NewResponse creates a new instance of Response.

ResolveResponseStatus returns the Response and HTTP status code that should be (or has been) sent for rw, given an optional error.

This function is useful for middleware and handlers that need to figure out the HTTP status code to return based on the error that occurred or what was set in the response.

Precedence rules:

  1. If the response has already been committed, the committed status wins (err is ignored).
  2. Otherwise, start with 200 OK (net/http default if WriteHeader is never called).
  3. If the response has a non-zero suggested status, use it.
  4. If err != nil, it overrides the suggested status: - StatusCode(err) if non-zero - otherwise 500 Internal Server Error.

UnwrapResponse unwraps given ResponseWriter to return contexts original Echo Response. rw has to implement following method `Unwrap() http.ResponseWriter`

func (r *Response) After(fn func())

After registers a function which is called just after the response is written.

func (r *Response) Before(fn func())

Before registers a function which is called just before the response (status) is written.

Unwrap returns the original http.ResponseWriter. ResponseController can be used to access the original http.ResponseWriter. See [https://go.dev/blog/go1.20]

Write writes the data to the connection as part of an HTTP reply.

func (r *Response) WriteHeader(code int)

WriteHeader sends an HTTP response header with status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.

Route contains information to adding/registering new route with the router. Method+Path pair uniquely identifies the Route. It is mandatory to provide Method+Path+Handler fields.

func (r Route) ToRouteInfo(params []string) RouteInfo

ToRouteInfo converts Route to RouteInfo

func (r Route) WithPrefix(pathPrefix string, middlewares []MiddlewareFunc) Route

WithPrefix recreates Route with added group prefix and group middlewares it is grouped to.

RouteInfo contains information about registered Route.

func (r RouteInfo) Clone() RouteInfo

Clone creates copy of RouteInfo

Reverse reverses route to URL string by replacing path parameters with given params values.

Router is interface for routing request contexts to registered routes.

Contract between Echo/Context instance and the router:

  • all routes must be added through methods on echo.Echo instance. Reason: Echo instance uses RouteInfo.Params() length to allocate slice for paths parameters (see `Echo.contextPathParamAllocSize`).
  • Router must populate Context during Router.Route call with:
  • Context.InitializeRoute (IMPORTANT! to reduce allocations use same slice that c.PathValues() returns)
  • Optionally can set additional information to Context with Context.Set
func NewConcurrentRouter(r Router) Router

NewConcurrentRouter creates concurrency safe Router which routes can be added/removed safely even after http.Server has been started.

type RouterConfig struct {
	NotFoundHandler           HandlerFunc
	MethodNotAllowedHandler   HandlerFunc
	OptionsMethodHandler      HandlerFunc
	AllowOverwritingRoute     bool
	UnescapePathParamValues   bool
	UseEscapedPathForMatching bool
}

RouterConfig is configuration options for (default) router

Routes is collection of RouteInfo instances with various helper methods.

func (r Routes) Clone() Routes

Clone creates copy of Routes

FilterByMethod searched for matching route info by method

FilterByName searched for matching route info by name

FilterByPath searched for matching route info by path

FindByMethodPath searched for matching route info by method and path

Reverse reverses route to URL string by replacing path parameters with given params values.

StartConfig is for creating configured http.Server instance to start serve http(s) requests with given Echo instance

Start starts given Handler with HTTP(s) server.

StartTLS starts given Handler with HTTPS server. If `certFile` or `keyFile` is `string` the values are treated as file paths. If `certFile` or `keyFile` is `[]byte` the values are treated as the certificate or key as-is.

type TemplateRenderer struct {
	Template interface {
		ExecuteTemplate(wr io.Writer, name string, data any) error
	}
}

TemplateRenderer is helper to ease creating renderers for `html/template` and `text/template` packages. Example usage:

	e.Renderer = &echo.TemplateRenderer{
		Template: template.Must(template.ParseGlob("templates/*.html")),
	}

  e.Renderer = &echo.TemplateRenderer{
		Template: template.Must(template.New("hello").Parse("Hello, {{.}}!")),
	}

Render renders the template with given data.

TimeLayout specifies the format for parsing time values in request parameters. It can be a standard Go time layout string or one of the special Unix time layouts.

TimeOpts is options for parsing time.Time values

type TrustOption func(*ipChecker)

TrustOption is config for which IP address to trust

TrustIPRange add trustable IP ranges using CIDR notation.

func TrustLinkLocal(v bool) TrustOption

TrustLinkLocal configures if you trust link-local address (default: true).

func TrustLoopback(v bool) TrustOption

TrustLoopback configures if you trust loopback address (default: true).

func TrustPrivateNet(v bool) TrustOption

TrustPrivateNet configures if you trust private network address (default: true).

type Validator interface {
	Validate(i any) error
}

Validator is the interface that wraps the Validate function.

ValueBinder provides utility methods for binding query or path parameter to various Go built-in types

func FormFieldBinder(c *Context) *ValueBinder

FormFieldBinder creates form field value binder For all requests, FormFieldBinder parses the raw query from the URL and uses query params as form fields

For POST, PUT, and PATCH requests, it also reads the request body, parses it as a form and uses query params as form fields. Request body parameters take precedence over URL query string values in r.Form.

NB: when binding forms take note that this implementation uses standard library form parsing which parses form data from BOTH URL and BODY if content type is not MIMEMultipartForm See https://golang.org/pkg/net/http/#Request.ParseForm

func PathValuesBinder(c *Context) *ValueBinder

PathValuesBinder creates path parameter value binder

func QueryParamsBinder(c *Context) *ValueBinder

QueryParamsBinder creates query parameter value binder

BindError returns first seen bind error and resets/empties binder errors for further calls

// example route function that binds query params to different destinations and stops binding on first bind error
failFastRouteFunc := func(c *echo.Context) error {
	var opts struct {
		IDs    []int64
		Active bool
	}
	length := int64(50) // default length is 50

	// create binder that stops binding at first error
	b := echo.QueryParamsBinder(c)

	err := b.Int64("length", &length).
		Int64s("ids", &opts.IDs).
		Bool("active", &opts.Active).
		BindError() // returns first binding error
	if err != nil {
		bErr := err.(*echo.BindingError)
		return fmt.Errorf("my own custom error for field: %s values: %v", bErr.Field, bErr.Values)
	}
	fmt.Printf("active = %v, length = %v, ids = %v\n", opts.Active, length, opts.IDs)

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

e := echo.New()
c := e.NewContext(
	httptest.NewRequest(http.MethodGet, "/api/endpoint?active=true&length=25&ids=1&ids=2&ids=3", nil),
	httptest.NewRecorder(),
)

_ = failFastRouteFunc(c)
Output:

active = true, length = 25, ids = [1 2 3]
func (b *ValueBinder) BindErrors() []error

BindErrors returns all bind errors and resets/empties binder errors for further calls

// example route function that binds query params to different destinations and returns all bind errors in one go
routeFunc := func(c *echo.Context) error {
	var opts struct {
		IDs    []int64
		Active bool
	}
	length := int64(50) // default length is 50

	b := echo.QueryParamsBinder(c)

	errs := b.Int64("length", &length).
		Int64s("ids", &opts.IDs).
		Bool("active", &opts.Active).
		BindErrors() // returns all errors
	if errs != nil {
		for _, err := range errs {
			bErr := err.(*echo.BindingError)
			log.Printf("in case you want to access what field: %s values: %v failed", bErr.Field, bErr.Values)
		}
		return fmt.Errorf("%v fields failed to bind", len(errs))
	}
	fmt.Printf("active = %v, length = %v, ids = %v", opts.Active, length, opts.IDs)

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

e := echo.New()
c := e.NewContext(
	httptest.NewRequest(http.MethodGet, "/api/endpoint?active=true&length=25&ids=1&ids=2&ids=3", nil),
	httptest.NewRecorder(),
)

_ = routeFunc(c)
Output:

active = true, length = 25, ids = [1 2 3]
func (b *ValueBinder) BindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder

BindUnmarshaler binds parameter to destination implementing BindUnmarshaler interface

BindWithDelimiter binds parameter to destination by suitable conversion function. Delimiter is used before conversion to split parameter value to separate values

Bool binds parameter to bool variable

Bools binds parameter values to slice of bool variables

Byte binds parameter to byte variable

CustomFunc binds parameter values with Func. Func is called only when parameter values exist.

// example route function that binds query params using custom function closure
routeFunc := func(c *echo.Context) error {
	length := int64(50) // default length is 50
	var binary []byte

	b := echo.QueryParamsBinder(c)
	errs := b.Int64("length", &length).
		CustomFunc("base64", func(values []string) []error {
			if len(values) == 0 {
				return nil
			}
			decoded, err := base64.URLEncoding.DecodeString(values[0])
			if err != nil {
				// in this example we use only first param value but url could contain multiple params in reality and
				// therefore in theory produce multiple binding errors
				return []error{echo.NewBindingError("base64", values[0:1], "failed to decode base64", err)}
			}
			binary = decoded
			return nil
		}).
		BindErrors() // returns all errors

	if errs != nil {
		for _, err := range errs {
			bErr := err.(*echo.BindingError)
			log.Printf("in case you want to access what field: %s values: %v failed", bErr.Field, bErr.Values)
		}
		return fmt.Errorf("%v fields failed to bind", len(errs))
	}
	fmt.Printf("length = %v, base64 = %s", length, binary)

	return c.JSON(http.StatusOK, "ok")
}

e := echo.New()
c := e.NewContext(
	httptest.NewRequest(http.MethodGet, "/api/endpoint?length=25&base64=SGVsbG8gV29ybGQ%3D", nil),
	httptest.NewRecorder(),
)
_ = routeFunc(c)
Output:

length = 25, base64 = Hello World

Duration binds parameter to time.Duration variable

Durations binds parameter values to slice of time.Duration variables

func (b *ValueBinder) FailFast(value bool) *ValueBinder

FailFast set internal flag to indicate if binding methods will return early (without binding) when previous bind failed NB: call this method before any other binding methods as it modifies binding methods behaviour

Float32 binds parameter to float32 variable

Float32s binds parameter values to slice of float32 variables

Float64 binds parameter to float64 variable

Float64s binds parameter values to slice of float64 variables

Int binds parameter to int variable

Int8 binds parameter to int8 variable

Int8s binds parameter to slice of int8

Int16 binds parameter to int16 variable

Int16s binds parameter to slice of int16

Int32 binds parameter to int32 variable

Int32s binds parameter to slice of int32

Int64 binds parameter to int64 variable

Int64s binds parameter to slice of int64

Ints binds parameter to slice of int

JSONUnmarshaler binds parameter to destination implementing json.Unmarshaler interface

func (b *ValueBinder) MustBindUnmarshaler(sourceParam string, dest BindUnmarshaler) *ValueBinder

MustBindUnmarshaler requires parameter value to exist to bind to destination implementing BindUnmarshaler interface. Returns error when value does not exist

MustBindWithDelimiter requires parameter value to exist to bind destination by suitable conversion function. Delimiter is used before conversion to split parameter value to separate values

MustBool requires parameter value to exist to bind to bool variable. Returns error when value does not exist

MustBools requires parameter values to exist to bind to slice of bool variables. Returns error when values does not exist

MustByte requires parameter value to exist to bind to byte variable. Returns error when value does not exist

MustCustomFunc requires parameter values to exist to bind with Func. Returns error when value does not exist.

MustDuration requires parameter value to exist to bind to time.Duration variable. Returns error when value does not exist

MustDurations requires parameter values to exist to bind to slice of time.Duration variables. Returns error when values does not exist

MustFloat32 requires parameter value to exist to bind to float32 variable. Returns error when value does not exist

MustFloat32s requires parameter values to exist to bind to slice of float32 variables. Returns error when values does not exist

MustFloat64 requires parameter value to exist to bind to float64 variable. Returns error when value does not exist

MustFloat64s requires parameter values to exist to bind to slice of float64 variables. Returns error when values does not exist

MustInt requires parameter value to exist to bind to int variable. Returns error when value does not exist

MustInt8 requires parameter value to exist to bind to int8 variable. Returns error when value does not exist

MustInt8s requires parameter value to exist to bind to int8 slice variable. Returns error when value does not exist

MustInt16 requires parameter value to exist to bind to int16 variable. Returns error when value does not exist

MustInt16s requires parameter value to exist to bind to int16 slice variable. Returns error when value does not exist

MustInt32 requires parameter value to exist to bind to int32 variable. Returns error when value does not exist

MustInt32s requires parameter value to exist to bind to int32 slice variable. Returns error when value does not exist

MustInt64 requires parameter value to exist to bind to int64 variable. Returns error when value does not exist

MustInt64s requires parameter value to exist to bind to int64 slice variable. Returns error when value does not exist

MustInts requires parameter value to exist to bind to int slice variable. Returns error when value does not exist

MustJSONUnmarshaler requires parameter value to exist to bind to destination implementing json.Unmarshaler interface. Returns error when value does not exist

MustString requires parameter value to exist to bind to string variable. Returns error when value does not exist

MustStrings requires parameter values to exist to bind to slice of string variables. Returns error when value does not exist

MustTextUnmarshaler requires parameter value to exist to bind to destination implementing encoding.TextUnmarshaler interface. Returns error when value does not exist

MustTime requires parameter value to exist to bind to time.Time variable. Returns error when value does not exist

MustTimes requires parameter values to exist to bind to slice of time.Time variables. Returns error when values does not exist

MustUint requires parameter value to exist to bind to uint variable. Returns error when value does not exist

MustUint8 requires parameter value to exist to bind to uint8 variable. Returns error when value does not exist

MustUint8s requires parameter value to exist to bind to uint8 slice variable. Returns error when value does not exist

MustUint16 requires parameter value to exist to bind to uint16 variable. Returns error when value does not exist

MustUint16s requires parameter value to exist to bind to uint16 slice variable. Returns error when value does not exist

MustUint32 requires parameter value to exist to bind to uint32 variable. Returns error when value does not exist

MustUint32s requires parameter value to exist to bind to uint32 slice variable. Returns error when value does not exist

MustUint64 requires parameter value to exist to bind to uint64 variable. Returns error when value does not exist

MustUint64s requires parameter value to exist to bind to uint64 slice variable. Returns error when value does not exist

MustUints requires parameter value to exist to bind to uint slice variable. Returns error when value does not exist

MustUnixTime requires parameter value to exist to bind to time.Duration variable (in local time corresponding to the given Unix time). Returns error when value does not exist.

Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal

MustUnixTimeMilli requires parameter value to exist to bind to time.Duration variable (in local time corresponding to the given Unix time in millisecond precision). Returns error when value does not exist.

Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal

MustUnixTimeNano requires parameter value to exist to bind to time.Duration variable (in local Time corresponding to the given Unix time value in nano second precision). Returns error when value does not exist.

Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00 Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00 Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
  • Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.

String binds parameter to string variable

Strings binds parameter values to slice of string

TextUnmarshaler binds parameter to destination implementing encoding.TextUnmarshaler interface

Time binds parameter to time.Time variable

Times binds parameter values to slice of time.Time variables

Uint binds parameter to uint variable

Uint8 binds parameter to uint8 variable

Uint8s binds parameter to slice of uint8

Uint16 binds parameter to uint16 variable

Uint16s binds parameter to slice of uint16

Uint32 binds parameter to uint32 variable

Uint32s binds parameter to slice of uint32

Uint64 binds parameter to uint64 variable

Uint64s binds parameter to slice of uint64

Uints binds parameter to slice of uint

UnixTime binds parameter to time.Time variable (in local Time corresponding to the given Unix time).

Example: 1609180603 bind to 2020-12-28T18:36:43.000000000+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal

UnixTimeMilli binds parameter to time.Time variable (in local time corresponding to the given Unix time in millisecond precision).

Example: 1647184410140 bind to 2022-03-13T15:13:30.140000000+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal

UnixTimeNano binds parameter to time.Time variable (in local time corresponding to the given Unix time in nanosecond precision).

Example: 1609180603123456789 binds to 2020-12-28T18:36:43.123456789+00:00 Example: 1000000000 binds to 1970-01-01T00:00:01.000000000+00:00 Example: 999999999 binds to 1970-01-01T00:00:00.999999999+00:00

Note:

  • time.Time{} (param is empty) and time.Unix(0,0) (param = "0") are not equal
  • Javascript's Number type only has about 53 bits of precision (Number.MAX_SAFE_INTEGER = 9007199254740991). Compare it to 1609180603123456789 in example.