Skip to content

webx-top/echo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,271 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Echo

Go Go Report Card 中文文档

Echo is a fast and unfancy web framework for Go (Golang). Up to 10x faster than the rest.

This package need >= go 1.25

Features

  • Optimized HTTP router which smartly prioritize routes.
  • Build robust and scalable RESTful APIs.
  • Run with standard HTTP server or FastHTTP server.
  • Group APIs.
  • Extensible middleware framework.
  • Define middleware at root, group or route level.
  • Handy functions to send variety of HTTP responses.
  • Centralized HTTP error handling.
  • Template rendering with multiple engine support (standard, Jet, SSE, etc).
  • Define your format for the logger.
  • Highly customizable.
  • Business error code system.
  • Form data filtering and binding.
  • Transaction support.
  • Reverse proxy with load balancing (random, round-robin).
  • URL rewriting with reverse/unrewrite support.
  • Rate limiting (with memory and Redis backends).
  • Request queue for concurrency control.
  • IP filtering.
  • Distributed tracing (OpenTracing).
  • Server-Sent Events (SSE).

Quick Start

Installation

$ go get github.com/webx-top/echo

Hello, World!

Create server.go

package main

import (
	"net/http"
	"github.com/webx-top/echo"
	"github.com/webx-top/echo/engine/standard"
)

func main() {
	e := echo.New()
	e.Get("/", func(c echo.Context) error {
		return c.String("Hello, World!", http.StatusOK)
	})
	e.Run(standard.New(":1323"))
}

Start server

$ go run server.go

Browse to http://localhost:1323 and you should see Hello, World! on the page.

Routing

e.Post("/users", saveUser)
e.Get("/users/:id", getUser)
e.Put("/users/:id", updateUser)
e.Delete("/users/:id", deleteUser)
e.Get("/user/<id:[\\d]+>", getUser)

Support two parameter syntaxes: :param and <param:regexp>.

Path Parameters

func getUser(c echo.Context) error {
	// User ID from path `users/:id`
	id := c.Param("id")
	// or id := c.Paramx("id").Uint64()
}

Query Parameters

/show?team=x-men&member=wolverine

func show(c echo.Context) error {
	// Get team and member from the query string
	team := c.Query("team")
	member := c.Query("member")
	age := c.Queryx("age").Uint()
}

Form application/x-www-form-urlencoded

POST /save

name value
name Joe Smith
email joe@labstack.com
func save(c echo.Context) error {
	// Get name and email
	name := c.Form("name")
	email := c.Form("email")
	age := c.Formx("age").Uint()
}

Form multipart/form-data

POST /save

name value
name Joe Smith
email joe@labstack.com
avatar avatar
func save(c echo.Context) error {
	// Get name and email
	name := c.Form("name")
	email := c.Form("email")

	//------------
	// Get avatar
	//------------
	_, err := c.SaveUploadedFile("avatar","./")
	return err
}

Handling Request

  • Bind JSON or XML payload into Go struct based on Content-Type request header.
  • Render response as JSON or XML with status code.
type User struct {
	Name  string `json:"name" xml:"name"`
	Email string `json:"email" xml:"email"`
}

e.Post("/users", func(c echo.Context) error {
	u := new(User)
	if err := c.MustBind(u); err != nil {
		return err
	}
	return c.JSON(u, http.StatusCreated)
	// or
	// return c.XML(u, http.StatusCreated)
})

Form Data Filter (FormFilter)

Filter and transform form data before binding.

import "github.com/webx-top/echo/formfilter"

ff := formfilter.New()
ff.Add(
    formfilter.StringToSlice("ids", ","),
    formfilter.DateRange("created", "2006-01-02"),
)

// Pass filter to Bind/MustBind directly
u := new(User)
c.MustBind(u, ff.Build())

Static Content

Serve any file from static directory for path /static/*.

e.Use(mw.Static(&mw.StaticOptions{
	Root:"static", // static file root directory
	Path:"/static/", // URL path for static files
	Browse:true, // show file list
}))

Embedded File Handler

Serve embedded files with index.html support via embed.FileSystems.

import "github.com/webx-top/echo/handler/embed"

//go:embed www/*
var wwwFS embed.FS

fs := embed.NewFileSystems()
fs.Register(wwwFS)
e.Get("/*", embed.File(fs))

Embedded Static Content (Bindata)

Serve go-bindata generated embedded static files as middleware.

import (
	"github.com/admpub/go-bindata-assetfs"
	"github.com/webx-top/echo/middleware/bindata"
)

//go:generate go-bindata -o=bindata_assetfs.go -pkg=main static/...
//go:generate go-bindata-assetfs -o=bindata_assetfs.go -pkg=main static/...

func NewAssetFS() *assetfs.AssetFS {
	return &assetfs.AssetFS{
		Asset:     Asset,     // generated by go-bindata
		AssetDir:  AssetDir,  // generated by go-bindata
		AssetInfo: AssetInfo, // generated by go-bindata
		Prefix:    "",
	}
}

e.Use(bindata.Static("/static/", NewAssetFS()))

Captcha

Image and audio captcha support.

import "github.com/webx-top/echo/handler/captcha"

captcha.DefaultOptions.Wrapper(e)
// Browse to /captcha/<id>.png

Middleware

// Root level middleware
e.Use(middleware.Log())
e.Use(middleware.Recover())

// Group level middleware
g := e.Group("/admin")
g.Use(middleware.BasicAuth(func(username, password string) bool {
	if username == "joe" && password == "secret" {
		return true
	}
	return false
}))

// Route level middleware
track := func(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		println("request to /users")
		return next.Handle(c)
	}
}
e.Get("/users", func(c echo.Context) error {
	return c.String("/users", http.StatusOK)
}, track)

Cookie

e.Get("/setcookie", func(c echo.Context) error {
	c.SetCookie("uid","1")
	return c.String("/setcookie: uid="+c.GetCookie("uid"), http.StatusOK)
})

Session

Session engine supports cookie-based and file-based storage.

...
import (
	...
	"github.com/webx-top/echo/middleware/session"
	cookieStore "github.com/webx-top/echo/middleware/session/engine/cookie"
)
...
sessionOptions := &echo.SessionOptions{
	Engine: `cookie`,
	Name:   `SESSIONID`,
	CookieOptions: &echo.CookieOptions{
		Path:     `/`,
		Domain:   ``,
		MaxAge:   0,
		Secure:   false,
		HttpOnly: true,
	},
}

cookieStore.RegWithOptions(&cookieStore.CookieOptions{
	KeyPairs: [][]byte{
		[]byte(`123456789012345678901234567890ab`),
	},
})

e.Use(session.Middleware(sessionOptions))

e.Get("/session", func(c echo.Context) error {
	c.Session().Set("uid",1).Save()
	return c.String(fmt.Sprintf("/session: uid=%v",c.Session().Get("uid")))
})

Transaction

Supports database transaction through context.

// Transaction interface
type Transaction interface {
	Begin(ctx context.Context) error
	Rollback(ctx context.Context) error
	Commit(ctx context.Context) error
	End(ctx context.Context, succeed bool) error
}

// Use in handler
c.Begin()
// ... operations
c.Commit()

Websocket

...
import (
	...
	"github.com/admpub/websocket"
	"github.com/webx-top/echo"
	ws "github.com/webx-top/echo/handler/websocket"
)
...

e.AddHandlerWrapper(ws.HanderWrapper)

e.Get("/websocket", func(c *websocket.Conn, ctx echo.Context) error {
	//push(writer)
	go func() {
		var counter int
		for {
			if counter >= 10 {
				return
			}
			time.Sleep(5 * time.Second)
			message := time.Now().String()
			ctx.Logger().Info(`Push message: `, message)
			if err := c.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
				ctx.Logger().Error(`Push error: `, err.Error())
				return
			}
			counter++
		}
	}()

	//echo
	ws.DefaultExecuter(c, ctx)
	return nil
})

More...

Sockjs

...
import (
	...
	"github.com/webx-top/echo"
	"github.com/admpub/sockjs-go/v3/sockjs"
	ws "github.com/webx-top/echo/handler/sockjs"
)
...

options := ws.Options{
	Handle: func(c sockjs.Session) error {
		//push(writer)
		go func() {
			var counter int
			for {
				if counter >= 10 {
					return
				}
				time.Sleep(5 * time.Second)
				message := time.Now().String()
				log.Info(`Push message: `, message)
				if err := c.Send(message); err != nil {
					log.Error(`Push error: `, err.Error())
					return
				}
				counter++
			}
		}()

		//echo
		ws.DefaultExecuter(c)
		return nil
	},
	Options: &sockjs.DefaultOptions,
	Prefix:  "/websocket",
}
options.Wrapper(e)

More...

Server-Sent Events (SSE)

import (
	_ "github.com/webx-top/echo/middleware/render/sse"
	"github.com/webx-top/echo/middleware/render"
)

e.Use(render.Middleware(render.New(`sse`, ``)))

e.Get("/events", func(c echo.Context) error {
	return c.SSEvent("message", listener)
})

Reverse Proxy

Built-in reverse proxy with load balancing support (Random, Round-Robin).

import "github.com/webx-top/echo/middleware"

// Round-Robin balancer
targets := []middleware.ProxyTargeter{
	&middleware.ProxyTarget{
		Name: "api-1",
		URL:  mustParseURL("http://localhost:8081"),
	},
	&middleware.ProxyTarget{
		Name: "api-2",
		URL:  mustParseURL("http://localhost:8082"),
	},
}
balancer := middleware.NewRoundRobinBalancer(targets)
e.Use(middleware.Proxy(balancer))

URL Rewrite

e.Use(middleware.Rewrite(map[string]string{
	"/old":              "/new",
	"/api/*":            "/$1",
	"/users/:id":        "/user/$1",
	"/users/*/orders/*": "/user/$1/order/$2",
}))

Request Queue

Limit concurrent request processing with queue timeout.

config := middleware.QueueConfig{
	QueueSize:     100,
	Workers:       10,
	QueueTimeout:  30 * time.Second,
	WorkerTimeout: 10 * time.Second,
}
e.Use(middleware.QueueWithConfig(config))

Request ID

e.Use(middleware.RequestID())
// Each response gets X-Request-ID header

IP Filter

import "github.com/webx-top/echo/middleware/ipfilter"

e.Use(ipfilter.IPFilter(ipfilter.Config{
	Options: ipfilter.Options{
		AllowedIPs: []string{"192.168.0.0/24"},
		BlockedIPs: []string{"0.0.0.0/0"},
	},
}))

OpenTracing

import "github.com/webx-top/echo/middleware/opentracing"

e.Use(opentracing.Trace(tracer))

Other Example

package main

import (
	"net/http"

	"github.com/webx-top/echo"
	// "github.com/webx-top/echo/engine/fasthttp"
	"github.com/webx-top/echo/engine/standard"
	mw "github.com/webx-top/echo/middleware"
)

func main() {
	e := echo.New()
	e.Use(mw.Log())

	e.Get("/", func(c echo.Context) error {
		return c.String("Hello, World!")
	})
	e.Get("/echo/:name", func(c echo.Context) error {
		return c.String("Echo " + c.Param("name"))
	})
	
	e.Get("/std", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`standard net/http handleFunc`))
		w.WriteHeader(200)
	})

	// FastHTTP
	// e.Run(fasthttp.New(":4444"))

	// Standard
	e.Run(standard.New(":4444"))
}

See other examples...

Middleware list

Root middleware (github.com/webx-top/echo/middleware)

Middleware Import path Description
BasicAuth github.com/webx-top/echo/middleware HTTP basic authentication
KeyAuth github.com/webx-top/echo/middleware API key authentication (header/query/form)
BodyLimit github.com/webx-top/echo/middleware Limit request body size
Gzip github.com/webx-top/echo/middleware Send gzip HTTP response
Secure github.com/webx-top/echo/middleware Protection against XSS, clickjacking, etc
CORS github.com/webx-top/echo/middleware Cross-Origin Resource Sharing
CSRF github.com/webx-top/echo/middleware Cross-Site Request Forgery
Log github.com/webx-top/echo/middleware Log HTTP requests
MethodOverride github.com/webx-top/echo/middleware Override request method via header
Recover github.com/webx-top/echo/middleware Recover from panics
HTTPSRedirect github.com/webx-top/echo/middleware Redirect HTTP to HTTPS
HTTPSWWWRedirect github.com/webx-top/echo/middleware Redirect HTTP to WWW HTTPS
WWWRedirect github.com/webx-top/echo/middleware Redirect non-WWW to WWW
NonWWWRedirect github.com/webx-top/echo/middleware Redirect WWW to non-WWW
AddTrailingSlash github.com/webx-top/echo/middleware Add trailing slash to URI
RemoveTrailingSlash github.com/webx-top/echo/middleware Remove trailing slash from URI
Static github.com/webx-top/echo/middleware Serve static files
MaxAllowed github.com/webx-top/echo/middleware Limit simultaneous requests
NoCache github.com/webx-top/echo/middleware Set no-cache headers
Rewrite github.com/webx-top/echo/middleware URL path rewriting
Proxy github.com/webx-top/echo/middleware Reverse proxy with load balancing
Queue github.com/webx-top/echo/middleware Request concurrency queue
RequestID github.com/webx-top/echo/middleware X-Request-ID header
Validate github.com/webx-top/echo/middleware Request validator injection
FuncMap github.com/webx-top/echo/middleware Template function map
AJAX github.com/webx-top/echo/middleware AJAX operation handler
Language github.com/webx-top/echo/middleware/language Multi-language (i18n) support
RateLimit github.com/webx-top/echo/middleware/ratelimit Rate limiting HTTP requests
RateLimiter github.com/webx-top/echo/middleware/ratelimiter Rate limiter (supports memory & Redis)
Session github.com/webx-top/echo/middleware/session Session manager
JWT github.com/webx-top/echo/middleware/jwt JWT authentication
Markdown github.com/webx-top/echo/middleware/markdown Markdown rendering
Render github.com/webx-top/echo/middleware/render HTML template rendering (standard, Jet, SSE)
IPFilter github.com/webx-top/echo/middleware/ipfilter IP address filtering
OpenTracing github.com/webx-top/echo/middleware/opentracing Distributed tracing
Bindata Static github.com/webx-top/echo/middleware/bindata Serve embedded static files
ReverseProxy github.com/webx-top/reverseproxy External reverse proxy

Handler Wrapper list

Wrapper Import path Description
Websocket github.com/webx-top/echo/handler/websocket Example
Sockjs github.com/webx-top/echo/handler/sockjs Example
Oauth2 github.com/webx-top/echo/handler/oauth2 Example
Pprof github.com/webx-top/echo/handler/pprof Go pprof profiler
Captcha github.com/webx-top/echo/handler/captcha Image & audio captcha
Embed github.com/webx-top/echo/handler/embed Embedded file system file server
SSE github.com/webx-top/echo/middleware/render/sse Server-Sent Events render driver

Template Func docs

Template Function Documentation

Template Data

When using the Render middleware, the data passed to c.Render(data) is wrapped into *echo.RenderData. In Go templates, call its exported methods via $.XXX:

{{$.Now}}           {{/* 当前时间 */}}
{{$.UnixTime}}      {{/* 当前时间戳 */}}
{{$.Site}}          {{/* 网站URL */}}
{{$.SiteRoot}}      {{/* 网站根路径 */}}
{{$.URL}}           {{/* 当前请求URL */}}
{{$.URI}}           {{/* 当前请求URI */}}
{{$.Path}}          {{/* 当前请求路径 */}}
{{$.Domain}}        {{/* 当前域名 */}}
{{$.Port}}          {{/* 当前端口 */}}
{{$.Scheme}}        {{/* http/https */}}
{{$.Lang}}          {{/* 当前语言 */}}
{{$.Referer}}       {{/* 来源地址 */}}
{{$.Query "key"}}   {{/* 获取查询参数 */}}
{{$.Form "key"}}    {{/* 获取表单参数 */}}
{{$.Param "key"}}   {{/* 获取路径参数 */}}
{{$.Get "key"}}     {{/* 获取Context中存储的值 */}}
{{$.Cookie}}        {{/* Cookie操作 */}}
{{$.Session}}       {{/* Session操作 */}}
{{$.Flash "key"}}   {{/* Flash消息 */}}
{{$.T "你好%v" "世界"}}  {{/* 多语言翻译 */}}
{{$.LangURI "zh"}}  {{/* 生成语言链接 */}}
{{$.URLByName "routeName" "param1"}}  {{/* 根据路由名生成URL */}}
{{$.CaptchaForm}}   {{/* 验证码表单 */}}
{{$.TimeAgo $time}} {{/* 时间友好显示 */}}
{{$.TsHumanize $time}}{{/* 时间区间友好显示 */}}
{{$.DurationFormat $t}}{{/* 持续时间格式化 */}}
{{$.Fetch "subtmpl" .}}{{/* 渲染子模板并嵌入 */}}
{{$.MakeURL "handler" "arg"}}{{/* 生成URL */}}
{{$.Ext}}           {{/* 默认扩展名 */}}
{{$.ThemeColor}}    {{/* 主题色 */}}
{{$.Prefix}}        {{/* 当前路由前缀 */}}
{{$.RootPrefix}}    {{/* 根路由前缀 */}}
{{$.UploadURL "subdir"}}{{/* 上传文件URL */}}
{{$.FullURL "/path"}}{{/* 生成完整URL */}}
{{$.HasAnyRequest}} {{/* 是否有任何请求数据 */}}
{{$.GetNextURL}}    {{/* 获取跳转URL */}}
{{$.ReturnToCurrentURL}}{{/* 返回当前URL */}}

$.Data is the original data passed to c.Render(), and $.Stored is read-only data set via c.Set("key",any).

Additional Packages

  • formfilter - Form data filtering utilities
  • subdomains - Subdomain routing utilities (with SafeMap)
  • code - Business error code system
  • code/register - Error code registration
  • encoding/dbconfig - Database configuration encoding
  • param - Parameter type utilities (StringSlice, StringMap, Store)
  • testing - HTTP testing utilities
  • mockcontext - Mock context for unit testing
  • defaults - Default configuration utilities
  • logger - Logger integrations

Cases

Credits

License

Apache 2

About

FastHTTP & net/http dual-engine web framework. Echo v2 enhanced version.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages