Skip to content

Latest commit

History

2,278 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Echo

GoGo 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"
)
funcmain() {
e:=echo.New()
e.Get("/", func(c echo.Context) error {
returnc.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

funcgetUser(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

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

Form application/x-www-form-urlencoded

POST/save

namevalue
nameJoe Smith
emailjoe@labstack.com
funcsave(c echo.Context) error {
// Get name and emailname:=c.Form("name")
email:=c.Form("email")
age:=c.Formx("age").Uint()
}

Form multipart/form-data

POST/save

namevalue
nameJoe Smith
emailjoe@labstack.com
avataravatar
funcsave(c echo.Context) error {
// Get name and emailname:=c.Form("name")
email:=c.Form("email")
//------------// Get avatar//------------_, err:=c.SaveUploadedFile("avatar","./")
returnerr
}

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.
typeUserstruct {
Namestring`json:"name" xml:"name"`Emailstring`json:"email" xml:"email"`
}
e.Post("/users", func(c echo.Context) error {
u:=new(User)
iferr:=c.MustBind(u); err!=nil {
returnerr
}
returnc.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 directlyu:=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 directoryPath:"/static/", // URL path for static filesBrowse: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/*varwwwFS embed.FSfs:=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/...funcNewAssetFS() *assetfs.AssetFS {
return&assetfs.AssetFS{
Asset: Asset, // generated by go-bindataAssetDir: AssetDir, // generated by go-bindataAssetInfo: AssetInfo, // generated by go-bindataPrefix: "",
}
}
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 middlewaree.Use(middleware.Log())
e.Use(middleware.Recover())
// Group level middlewareg:=e.Group("/admin")
g.Use(middleware.BasicAuth(func(username, passwordstring) bool {
ifusername=="joe"&&password=="secret" {
returntrue
}
returnfalse
}))
// Route level middlewaretrack:=func(next echo.HandlerFunc) echo.HandlerFunc {
returnfunc(c echo.Context) error {
println("request to /users")
returnnext.Handle(c)
}
}
e.Get("/users", func(c echo.Context) error {
returnc.String("/users", http.StatusOK)
}, track)

Cookie

e.Get("/setcookie", func(c echo.Context) error {
c.SetCookie("uid","1")
returnc.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()
returnc.String(fmt.Sprintf("/session: uid=%v",c.Session().Get("uid")))
})

Transaction

Supports database transaction through context.

// Transaction interfacetypeTransactioninterface {
Begin(ctx context.Context) errorRollback(ctx context.Context) errorCommit(ctx context.Context) errorEnd(ctx context.Context, succeedbool) error
}
// Use in handlerc.Begin()
// ... operationsc.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)gofunc() {
varcounterintfor {
ifcounter>=10 {
return
}
time.Sleep(5*time.Second)
message:=time.Now().String()
ctx.Logger().Info(`Push message: `, message)
iferr:=c.WriteMessage(websocket.TextMessage, []byte(message)); err!=nil {
ctx.Logger().Error(`Push error: `, err.Error())
return
}
counter++
}
}()
//echows.DefaultExecuter(c, ctx)
returnnil
})

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)gofunc() {
varcounterintfor {
ifcounter>=10 {
return
}
time.Sleep(5*time.Second)
message:=time.Now().String()
log.Info(`Push message: `, message)
iferr:=c.Send(message); err!=nil {
log.Error(`Push error: `, err.Error())
return
}
counter++
}
}()
//echows.DefaultExecuter(c)
returnnil
},
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 {
returnc.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 balancertargets:= []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"
)
funcmain() {
e:=echo.New()
e.Use(mw.Log())
e.Get("/", func(c echo.Context) error {
returnc.String("Hello, World!")
})
e.Get("/echo/:name", func(c echo.Context) error {
returnc.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"))// Standarde.Run(standard.New(":4444"))
}

See other examples...

Middleware list

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

MiddlewareImport pathDescription
BasicAuthgithub.com/webx-top/echo/middlewareHTTP basic authentication
KeyAuthgithub.com/webx-top/echo/middlewareAPI key authentication (header/query/form)
BodyLimitgithub.com/webx-top/echo/middlewareLimit request body size
Gzipgithub.com/webx-top/echo/middlewareSend gzip HTTP response
Securegithub.com/webx-top/echo/middlewareProtection against XSS, clickjacking, etc
CORSgithub.com/webx-top/echo/middlewareCross-Origin Resource Sharing
CSRFgithub.com/webx-top/echo/middlewareCross-Site Request Forgery
Loggithub.com/webx-top/echo/middlewareLog HTTP requests
MethodOverridegithub.com/webx-top/echo/middlewareOverride request method via header
Recovergithub.com/webx-top/echo/middlewareRecover from panics
HTTPSRedirectgithub.com/webx-top/echo/middlewareRedirect HTTP to HTTPS
HTTPSWWWRedirectgithub.com/webx-top/echo/middlewareRedirect HTTP to WWW HTTPS
WWWRedirectgithub.com/webx-top/echo/middlewareRedirect non-WWW to WWW
NonWWWRedirectgithub.com/webx-top/echo/middlewareRedirect WWW to non-WWW
AddTrailingSlashgithub.com/webx-top/echo/middlewareAdd trailing slash to URI
RemoveTrailingSlashgithub.com/webx-top/echo/middlewareRemove trailing slash from URI
Staticgithub.com/webx-top/echo/middlewareServe static files
MaxAllowedgithub.com/webx-top/echo/middlewareLimit simultaneous requests
NoCachegithub.com/webx-top/echo/middlewareSet no-cache headers
Rewritegithub.com/webx-top/echo/middlewareURL path rewriting
Proxygithub.com/webx-top/echo/middlewareReverse proxy with load balancing
Queuegithub.com/webx-top/echo/middlewareRequest concurrency queue
RequestIDgithub.com/webx-top/echo/middlewareX-Request-ID header
Validategithub.com/webx-top/echo/middlewareRequest validator injection
FuncMapgithub.com/webx-top/echo/middlewareTemplate function map
AJAXgithub.com/webx-top/echo/middlewareAJAX operation handler
Languagegithub.com/webx-top/echo/middleware/languageMulti-language (i18n) support
RateLimitgithub.com/webx-top/echo/middleware/ratelimitRate limiting HTTP requests
RateLimitergithub.com/webx-top/echo/middleware/ratelimiterRate limiter (supports memory & Redis)
Sessiongithub.com/webx-top/echo/middleware/sessionSession manager
JWTgithub.com/webx-top/echo/middleware/jwtJWT authentication
Markdowngithub.com/webx-top/echo/middleware/markdownMarkdown rendering
Rendergithub.com/webx-top/echo/middleware/renderHTML template rendering (standard, Jet, SSE)
IPFiltergithub.com/webx-top/echo/middleware/ipfilterIP address filtering
OpenTracinggithub.com/webx-top/echo/middleware/opentracingDistributed tracing
Bindata Staticgithub.com/webx-top/echo/middleware/bindataServe embedded static files
ReverseProxygithub.com/webx-top/reverseproxyExternal reverse proxy

Handler Wrapper list

WrapperImport pathDescription
Websocketgithub.com/webx-top/echo/handler/websocketExample
Sockjsgithub.com/webx-top/echo/handler/sockjsExample
Oauth2github.com/webx-top/echo/handler/oauth2Example
Pprofgithub.com/webx-top/echo/handler/pprofGo pprof profiler
Captchagithub.com/webx-top/echo/handler/captchaImage & audio captcha
Embedgithub.com/webx-top/echo/handler/embedEmbedded file system file server
SSEgithub.com/webx-top/echo/middleware/render/sseServer-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

Stars

69 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages