High performance, minimalist Go web framework

Sourcegraph GoDoc Go Report Card Build Status Codecov Join the chat at https://gitter.im/labstack/echo Forum Twitter License

Supported Go versions

As of version 4.0.0, Echo is available as a Go module. Therefore a Go version capable of understanding /vN suffixed imports is required:

  • 1.9.7+
  • 1.10.3+
  • 1.14+

Any of these versions will allow you to import Echo as github.com/labstack/echo/v4 which is the recommended way of using Echo going forward.

For older versions, please use the latest v3 tag.

Feature Overview

  • Optimized HTTP router which smartly prioritize routes
  • Build robust and scalable RESTful APIs
  • Group APIs
  • Extensible middleware framework
  • Define middleware at root, group or route level
  • Data binding for JSON, XML and form payload
  • Handy functions to send variety of HTTP responses
  • Centralized HTTP error handling
  • Template rendering with any template engine
  • Define your format for the logger
  • Highly customizable
  • Automatic TLS via Let’s Encrypt
  • HTTP/2 support

Benchmarks

Date: 2020/11/11
Source: https://github.com/vishr/web-framework-benchmark
Lower is better!

The benchmarks above were run on an Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz

Guide

Installation

// go get github.com/labstack/echo/{version}
go get github.com/labstack/echo/v4

Example

package main

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

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

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

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

  // Start server
  e.Logger.Fatal(e.Start(":1323"))
}

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

Help

Contribute

Use issues for everything

  • For a small change, just send a PR.
  • For bigger changes open an issue for discussion before sending a PR.
  • PR should have:
    • Test case
    • Documentation
    • Example (If it makes sense)
  • You can also contribute by:
    • Reporting issues
    • Suggesting new features or enhancements
    • Improve/fix documentation

Credits

License

MIT

Comments
  • Echo v3

    Echo v3

    Making Echo as simple as it was in v1

    • [x] Drop fasthttp support to keep the project simple, easy to maintain, aligned with standard library and compatible with community packages. As simple as it was in v1.
    • [x] Skipper function to conditionally skip a middleware
    • [x] Update docs
    • [x] Update recipes
      • [x] Put back WebSocket
      • [x] Put back Graceful shutdown
    • [x] Release notes and migrating guide
    • [x] Use standard lib for serving files #471
    • [x] Wrap standard handler
    • [x] Wrap standard middleware
    • [x] Auto TLS via https://letsencrypt.org
    • [x] Map type as shorthand for map[string]interface{}
    • [x] Built-in graceful shutdown
    • [x] https://github.com/labstack/echo/issues/669#issuecomment-252396200
    • [x] Remove static middleware
    • [x] and more...

    @ericmdantas @o1egl @CaptainCodeman @mtojek @Anon-Penguin @gavv @01walid @ipfans @matcornic

    Open for discussion

  • Tags are breaking after v3.2.1

    Tags are breaking after v3.2.1

    Prior to version 3.2.1 inclusive, tags had the format v3.2.1, which was correct and works for Dep / Go modules (vgo). After version 3.2.1 (>=3.2.2), you use a tag format 3.2.2 that is incompatible with Go modules (vgo).

    If you try to use Go modules (vgo, go1.11 was released), than you see something like this:

    require (
    ...
    github.com/labstack/echo v0.0.0-20180412143600-6d227dfea4d2
    ...
    )
    

    Main changes that was done in 3.2.2, tag name:

    • before vX.Y.Z
    • after X.Y.Z

    v was dropped 😔

  • Who's using Echo?

    Who's using Echo?

    If you are using Echo in your personal projects or at work, please consider getting it listed on README.

    • Synack
    • Software Motor
    • https://cozy.io

    PS: Just mention as a comment.

  • "binding element must be a struct" introduced with path params binding

    Issue Description

    This is simillar to #988 and introduced by https://github.com/labstack/echo/commit/858270f6f5e4fd02d9e147e8a6b0d97df023f14b in a specific situation: taking the address of your struct twice and sending it to bind.

    u := &user{}
    c.Bind(&u)
    

    Because of the newly introduced params binding, when the struct's type is checked, it fails here:

    func (b *DefaultBinder) bindData(ptr interface{}, data map[string][]string, tag string) error {
    	typ := reflect.TypeOf(ptr).Elem()
    	val := reflect.ValueOf(ptr).Elem()
    
    	if typ.Kind() != reflect.Struct {
    		return errors.New("binding element must be a struct")
    	}
    

    Before the params binding was introduced, bindData was not called for POST/PUT/PATCH, because for these methods you directly decode the body into the given struct.

    And a mention: If you have id both as path param and json property in the request body, the value from the body will overwrite the one from the path. This could lead to confusion and bugs in projects.

    Checklist

    • [x] Dependencies installed
    • [x] No typos
    • [x] Searched existing issues and docs

    Expected behaviour

    If this is known and planned for next major version, than it's OK, else compatibility should not be broken.

    Actual behaviour

    See Expected behaviour

    Steps to reproduce

    Take the address of the struct sent at bind twice and make a request to a server (see Working code to debug).

    curl -X PUT -H "Content-Type: application/json" -d '{"name":"John"}' localhost:8811/users/1
    

    Working code to debug

    package main
    
    import (
    	"github.com/labstack/echo/v4"
    	"github.com/labstack/echo/v4/middleware"
    	"github.com/labstack/gommon/log"
    )
    
    type user struct {
    	ID int `json:"id" param:"id"`
    	Name string `json:"name"`
    }
    
    func main() {
    	s := echo.New()
    	s.Use(middleware.Logger())
    
    	s.PUT("/users/:id", func(c echo.Context) error {
    		u := &user{}
    		if err := c.Bind(&u); err != nil {
    			log.Fatal(err)
    		}
    		log.Print(u)
    		return nil
    	})
    
    	s.Start(":8811")
    }
    

    Version/commit

    https://github.com/labstack/echo/commit/858270f6f5e4fd02d9e147e8a6b0d97df023f14b

  • HttpOnly cookie of CSRF token

    HttpOnly cookie of CSRF token

    As mentioned in Wikipedia:

    An HttpOnly cookie cannot be accessed by client-side APIs, such as JavaScript.

    I updated the echo to last version and now the csrf cookie is HttpOnly enabled. Thus it is not possible to get data using AJAX.

  • Echo v5

    Echo v5

    Let me know what you want to see in v5 ✌️

    Here are my thoughts?

    • ~~I don't like Context as an interface, we did it to expand on it using a custom context; however, casting it back in handler is tedious~~
    • Simplified middleware signature like in v1/v2? making it easier to write a middleware.
    • Bind path parameters
    • Merge https://github.com/labstack/echo/pull/1328 with JWTErrorHandler (How about adding next to the handler so you can rely on next auth handler)
  • nested resources and named params problem

    nested resources and named params problem

    I have the nested resource routes, below case will be failed:

        r.Add("GET", "/users/new", func(*Context) {}, nil)
        r.Add("GET", "/users/wen", func(*Context) {}, nil)
        r.Add("GET", "/users/:id", func(*Context) {}, nil)
        r.Add("GET", "/users/:userId/photos/:photoId/comments/:id", func(*Context) {}, nil)
        h, _, _ := r.Find(MethodGET, "/users/233/photos/377/comments/610")
        if h == nil {
            t.Fatal("handle not found")
        }
    
    

    Tree

    └── /users/ has=0, h=<nil>, echo=0, edges=3
        ├── new has=0, h=0x6e8a0, echo=0, edges=0
        ├── wen has=0, h=0x6e8b0, echo=0, edges=0
        └── : has=0, h=<nil>, echo=0, edges=2
            ├── id has=0, h=0x6e8c0, echo=0, edges=0
            └── userId has=0, h=<nil>, echo=0, edges=1
                └── /photos/ has=1, h=<nil>, echo=0, edges=1
                    └── :photoId has=0, h=<nil>, echo=0, edges=1
                        └── /comments/ has=1, h=<nil>, echo=0, edges=1
                            └── :id has=0, h=0x6e8d0, echo=0, edges=0
    
  • Add support for a Scanner interface.

    Add support for a Scanner interface.

    This duplicates the Scanner interface implemented by the standard library's sql package, extending echo's standard Binder to support arbitrary data types, so long as they implement this interface.

    This solves #763.

  • Work around issue#1244

    Work around issue#1244

    • go.mod module name changed github.com/labstack/echo -> github.com/labstack/echo/v3
    • replace imports with .../echo/v3...

    PS: if I correctly understand #1244


    cc @vishr @alexaandru

  • Echo v2 proposal

    Echo v2 proposal

    https://github.com/labstack/echo/tree/v2

    • [x] Echo.Context as interface #146
    • [x] Request, Response and their fields as interface
      • Enables easy testing and loading context with your own functions.
    • [x] Decoupling from standard HTTP API which allows you use any HTTP engine underneath, for example, fasthttp. #290
    • [x] Drop Context#JSONIndent and Context#XMLIndent and use formatting while debug is on
    • [x] JSONBlob 4e57fa0557593aea5f1b8fdd26d64c09e81a108c
    • [x] AutoIndex as middleware
    • [x] Fix Context#Redirect
    • [x] https://github.com/labstack/echo/pull/355
    • [x] Binder https://github.com/labstack/echo/pull/352/files
    • [x] https://github.com/labstack/echo/issues/307
    • [x] a81670211f64a31cee96c177e799780a25fc6d5a
    • [x] https://github.com/labstack/echo/pull/338
    • [x] https://github.com/labstack/echo/pull/358
    • [x] Wrapper for handler
    • [x] Wrapper for middleware
    • [x] https://github.com/labstack/echo/commit/49fb8a5c62c91767df37884219e4c6ecd9964e74
    • [x] Godoc
    • [x] Website
      • [x] https://github.com/labstack/echo/issues/369#issuecomment-205732520

    Open for discussion!

  • Introduced Go module support as v4, removed obsolete CloseNotifier()

    Introduced Go module support as v4, removed obsolete CloseNotifier()

    This reintroduces support for Go modules, as v4

    CloseNotifier() is removed as it has been obsoleted, see https://golang.org/doc/go1.11#net/http It was already NOT working (not sending signals) as of 1.11, the functionality was gone already, we merely deleted the functions that exposed it. If everyone still rely on it they should migrate to using c.Request().Context().Done() instead.

    Closes #1268, #1255

  • my validation won't work after binding request data

    my validation won't work after binding request data

    hi guys, i wanna ask why i got error reflect: reflect.Value.Set using unaddressable value when i call c.Validate() but when i tried to pass dummy data(not from payload) the validation works

    i've done trying using ampersand before passing my value but the error is still the same

    sorry about my written issue, this is my first ever post. Thx guys!

    type UserControllerImpl struct { UserService service.UserService // Validate *validator.Validate }

    func NewUserController(userService service.UserService) *UserControllerImpl { return &UserControllerImpl{ UserService: userService, // Validate: validate, } }

    func (controller *UserControllerImpl) Create(c echo.Context) error { userRequest := new(dto.UserCreateRequest)

    errBind := c.Bind(userRequest)
    if errBind != nil {
    	return c.JSON(http.StatusBadRequest, ch.ResponseOkNoData(fmt.Sprintf("failed: "+errBind.Error())))
    }
    
    errVal := c.Validate(userRequest) 
    // errVal := controller.Validate.Struct(userRequest)
    if errVal != nil {
    	return c.JSON(http.StatusBadRequest, ch.ResponseOkNoData(fmt.Sprintf("failed: "+errVal.Error())))
    }
    
    result, err := controller.UserService.Create(*userRequest)
    if err != nil {
    	return c.JSON(http.StatusBadRequest, ch.ResponseOkNoData("your email or handphone number is already registered"))
    }
    
    return c.JSON(http.StatusCreated, ch.ResponseOkWithData("create data user success", result))
    

    }

  • Warn users with debug enabled that middleware errors are not handled

    Warn users with debug enabled that middleware errors are not handled

    Warn users with debug enabled that middleware errors are not handled

    Users may not expect errors thrown in the middleware on the response path flow to be ignored if the response has been committed by a handler

  • fix: setCookie avoid security breach

    fix: setCookie avoid security breach

  • Proxy middleware should detect broken backends and switch to healthy backends

    Proxy middleware should detect broken backends and switch to healthy backends

    Issue Description

    Currently, if a backend is down, Echo will return an error when it attempts to connect to it.

    Expected behaviour

    It would be a great feature for Echo's Proxy middleware to automatically iterate over remaining backends until one returns a successful connection.

    Actual behaviour

    Echo will return an error when it attempts to connect to a backend that is down.

    Version/commit

    4.9.0

  • Is there a way to assign result from rendering template

    Is there a way to assign result from rendering template

    How I can assign result from rendering template to send this value as json, for ajax call

    my example:

    func Load(c echo.Context) error {
        params := map[string]any{
            "btn_style":  "btn-light btn-sm",
        }
        
        if err := c.Render(http.StatusOK, "test.tmpl", params); err != nil {
            return err
        }
        
        payload := []byte(fmt.Sprintf(`{"payload":"%s"}`, c.Get("tmpl").(string)))
        
        fmt.Println(string(payload))
        
        return c.JSONBlob(http.StatusOK, (payload))
    }
    

    Render function

    func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
        var buf bytes.Buffer
    
        err := t.templates.ExecuteTemplate(&buf, name, data)
        if err != nil {
            return err
        }
    
        c.Set("tmpl", buf.String())
    
        return t.templates.ExecuteTemplate(w, name, data)
    }
    
  • Bind{Query,Path}Params panic on non pointer value

    Bind{Query,Path}Params panic on non pointer value

    Here #1446 trying to address this issue but it never came into reality for no reason! BTW it's a bug as framework should not panic instead it should handle this situation gracefully!

    UPDATE: Should i pr the changes needed to remedy the situation as it seems pretty straightforward to me?

beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 1, 2023
Gearbox :gear: is a web framework written in Go with a focus on high performance
Gearbox :gear: is a web framework written in Go with a focus on high performance

gearbox ⚙️ is a web framework for building micro services written in Go with a focus on high performance. It's built on fasthttp which is up to 10x fa

Jan 3, 2023
hiboot is a high performance web and cli application framework with dependency injection support

Hiboot - web/cli application framework About Hiboot is a cloud native web and cli application framework written in Go. Hiboot is not trying to reinven

Nov 20, 2022
Gearbox :gear: is a web framework written in Go with a focus on high performance
Gearbox :gear: is a web framework written in Go with a focus on high performance

gearbox ⚙️ is a web framework for building micro services written in Go with a focus on high performance. It's built on fasthttp which is up to 10x fa

Dec 29, 2022
High performance, simple Go web framework

Elton Elton的实现参考了koa以及echo,中间件的调整均为洋葱模型:请求由外至内,响应由内至外。主要特性如下: 处理函数(中间件)均以返回error的形式响应出错,方便使用统一的出错处理中间件将出错统一转换为对应的输出(JSON),并根据出错的类型等生成各类统计分析 成功响应数据直接赋值

Dec 17, 2022
beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 8, 2023
letgo is an open-source, high-performance web framework for the Go programming language.

high-performance Lightweight web framework for the Go programming language. golang web framework,高可用golang web框架,go语言 web框架 ,go web

Sep 23, 2022
Dragon 🐲 🐲 🐲 is an enterprise high performance web framework with Go for the feature and comfortable develop.

Dragon start dragon ab performance Dragon ?? ?? ?? is a lightweight high performance web framework with Go for the feature and comfortable develop. 中文

Sep 14, 2022
Dragon 🐲 🐲 🐲 is a lightweight high performance web framework with Go for the feature and comfortable develop.

Dragon project new link start dragon ab performance Dragon ?? ?? ?? is a lightweight high performance web framework with Go for the feature and comfor

Sep 6, 2022
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.

GoFrame English | 简体中文 GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang. If you're a

Jan 2, 2023
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.

Flamingo Framework Flamingo is a web framework based on Go. It is designed to build pluggable and maintainable web projects. It is production ready, f

Jan 5, 2023
Golanger Web Framework is a lightweight framework for writing web applications in Go.

/* Copyright 2013 Golanger.com. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

Nov 14, 2022
The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework.

jin About The jin is a simplified version of the gin web framework that can help you quickly understand the core principles of a web framework. If thi

Jul 14, 2022
Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance. Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。
Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance.  Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。

Tigo(For English Documentation Click Here) 一个使用Go语言开发的web框架。 相关工具及插件 tiger tiger是一个专门为Tigo框架量身定做的脚手架工具,可以使用tiger新建Tigo项目或者执行其他操作。

Jan 5, 2023
Package macaron is a high productive and modular web framework in Go.
Package macaron is a high productive and modular web framework in Go.

Macaron Package macaron is a high productive and modular web framework in Go. Getting Started The minimum requirement of Go is 1.6. To install Macaron

Jan 2, 2023
A high productivity, full-stack web framework for the Go language.

Revel Framework A high productivity, full-stack web framework for the Go language. Current Version: 1.0.0 (2020-07-11) Supports go.mod package managem

Jan 7, 2023
Goal is a toolkit for high productivity web development in Go language in the spirit of Revel Framework that is built around the concept of code generation.

Goal Goal is a set of tools for high productivity web development in Go language. Goal, being mostly inspired by Revel Framework and its discussions,

Sep 27, 2021
A high level web-framework for Go

go-start is a high level web-framework for Go, like Django for Python or Rails for Ruby. Installation: go get github.com/ungerik/go-start Documentatio

Dec 24, 2022
⚡ Rux is an simple and fast web framework. support middleware, compatible http.Handler interface. 简单且快速的 Go web 框架,支持中间件,兼容 http.Handler 接口

Rux Simple and fast web framework for build golang HTTP applications. NOTICE: v1.3.x is not fully compatible with v1.2.x version Fast route match, sup

Dec 8, 2022