Faygo is a fast and concise Go Web framework that can be used to develop high-performance web app(especially API) with fewer codes. Just define a struct Handler, Faygo will automatically bind/verify the request parameters and generate the online API doc. Go to <User Manual>
v1.2.0
Go Version ≥ 1.8
- Way 1: download source
go get -u -v github.com/andeya/faygo
- Way 2: deployment tools (Go to fay)
go get -u -v github.com/andeya/fay
fay command [arguments] The commands are: new create, compile and run (monitor changes) a new faygo project run compile and run (monitor changes) an any existing go project fay new appname [apptpl] appname specifies the path of the new faygo project apptpl optionally, specifies the faygo project template type fay run [appname] appname optionally, specifies the path of the new project
- One
struct Handler
can get more things:
- Define Handler/Middleware
- Bind and verify request parameters
- Generate an online document for the Swagger 2.0 API
- Database ORM mapping
- Handler and Middleware are exactly the same, both implement the Handler interface (
func
orstruct
), which together constitute the handler chain of the router. - Supports multiple network types:
Network types | Configuration net_types |
---|---|
HTTP | http |
HTTPS/HTTP2(TLS) | https |
HTTPS/HTTP2(Let's Encrypt TLS) | letsencrypt |
HTTPS/HTTP2(Let's Encrypt TLS on UNIX socket) | unix_letsencrypt |
HTTP(UNIX socket) | unix_http |
HTTPS/HTTP2(TLS on UNIX socket) | unix_https |
- Support single-service & single-listener, single-service & multi-listener, multi-service & multi-listener and so on. The config of multiple services is independent of each other
- The high-performance router based on
httprouter
supports both chain and tree registration styles; supports flexible static file router (such as DirFS, RenderFS, MarkdownFS, etc.) - Support graceful shutdown and rebooting, provide fay tools which has new projects, hot compilation , meta programming function
- Use the most powerful
pongo2
as the HTML rendering engine - Support near-LRU memory caching (mainly used for static file cache)
- Support cross-platform color log system, and has two output interface(console and file)
- Support session management (If you use a persistent storage engine, you must use gob.Register() to register the relevant custom type before starting the service)
- Support global gzip compression config
- Support XSRF security filtering
- Most features try to use simple ini configs to avoid unnecessary recompilation, and these profiles can be automatically assigned default values
- Provide
gorm
,xorm
,sqlx
,directSQL
,Websocket
,ini
,http client
and many other commonly used expansion packages
package main import ( // "mime/multipart" "time" "github.com/andeya/faygo" ) type Index struct { Id int `param:"<in:path> <required> <desc:ID> <range: 0:10>"` Title string `param:"<in:query> <nonzero>"` Paragraph []string `param:"<in:query> <name:p> <len: 1:10> <regexp: ^[\\w]*$>"` Cookie string `param:"<in:cookie> <name:faygoID>"` // Picture *multipart.FileHeader `param:"<in:formData> <name:pic> <maxmb:30>"` } func (i *Index) Serve(ctx *faygo.Context) error { if ctx.CookieParam("faygoID") == "" { ctx.SetCookie("faygoID", time.Now().String()) } return ctx.JSON(200, i) } func main() { app := faygo.New("myapp", "0.1") // Register the route in a chain style app.GET("/index/:id", new(Index)) // Register the route in a tree style // app.Route( // app.NewGET("/index/:id", new(Index)), // ) // Start the service faygo.Run() } /* http GET: http://localhost:8080/index/1?title=test&p=abc&p=xyz response: { "Id": 1, "Title": "test", "Paragraph": [ "abc", "xyz" ], "Cookie": "2016-11-13 01:14:40.9038005 +0800 CST" } */
Handler and middleware are the same, both implemente Handler interface!
- function type
// Page handler doesn't contains API doc description func Page() faygo.HandlerFunc { return func(ctx *faygo.Context) error { return ctx.String(200, "faygo") } } // Page2 handler contains API doc description var Page2 = faygo.WrapDoc(Page(), "test page2 notes", "test")
- struct type
// Param binds and validates the request parameters by Tags type Param struct { Id int `param:"<in:path> <required> <desc:ID> <range: 0:10>"` Title string `param:"<in:query>"` } // Serve implemente Handler interface func (p *Param) Serve(ctx *faygo.Context) error { return ctx.JSON(200, faygo.Map{ "Struct Params": p, "Additional Param": ctx.PathParam("additional"), }, true) } // Doc implemente API Doc interface (optional) func (p *Param) Doc() faygo.Doc { return faygo.Doc{ // Add the API notes to the API doc Note: "param desc", // declare the response content format to the API doc Return: faygo.JSONMsg{ Code: 1, Info: "success", }, // additional request parameter declarations to the API doc (optional) Params: []faygo.ParamInfo{ { Name: "additional", In: "path", Model: "a", Desc: "defined by the `Doc()` method", }, }, } }
The filter function must be HandleFunc type!
func Root2Index(ctx *faygo.Context) error { // Direct access to `/index` is not allowed if ctx.Path() == "/index" { ctx.Stop() return nil } if ctx.Path() == "/" { ctx.ModifyPath("/index") } return nil }
- tree style
// New application object, params: name, version var app1 = faygo.New("myapp1", "1.0") // router app1.Filter(Root2Index). Route( app1.NewNamedGET("test page", "/page", Page()), app1.NewNamedGET("test page2", "/page2", Page2), app1.NewGroup("home", app1.NewNamedGET("test param", "/param", &Param{ // sets the default value in the API documentation for the request parameters (optional) Id: 1, Title: "test param", }), ), )
- chain style
// New application object, params: name, version var app2 = faygo.New("myapp2", "1.0") // router app2.Filter(Root2Index) app2.NamedGET("test page", "/page", Page()) app2.NamedGET("test page2", "/page2", Page2) app2.Group("home") { app2.NamedGET("test param", "/param", &Param{ // sets the default value in the API documentation for the request parameters(optional) Id: 1, Title: "test param", }) }
- shutdown gracefully
kill [pid]
- reboot gracefully
kill -USR2 [pid]
- Each instance of the application has a single config (file name format
config/{appname}[_{version}].ini
). Refer to the following:
net_types = http|https # List of network type: http | https | unix_http | unix_https | letsencrypt | unix_letsencrypt addrs = 0.0.0.0:80|0.0.0.0:443 # List of multiple listening addresses tls_certfile = # TLS certificate file path tls_keyfile = # TLS key file path letsencrypt_dir = # Let's Encrypt TLS certificate cache directory unix_filemode = 0666 # File permissions for UNIX listener, requires octal number http_redirect_https = false # Redirect from 'http://hostname:port1' to 'https://hostname:port2' read_timeout = 0s # Maximum duration for reading the full; ns|µs|ms|s|m|h request (including body) write_timeout = 0s # Maximum duration for writing the full; ns|µs|ms|s|m|h response (including body) multipart_maxmemory_mb = 32 # Maximum size of memory that can be used when receiving uploaded files slow_response_threshold= 0s # When response time > slow_response_threshold, log level = 'WARNING'; 0 means not limited; ns|µs|ms|s|m|h print_body = false # Form requests are printed in JSON format, but other types are printed as-is [router] # Routing config section redirect_trailing_slash = true # Automatic redirection (for example, `/foo/` -> `/foo`) redirect_fixed_path = true # Tries to fix the current request path, if no handle is registered for it handle_method_not_allowed = true # Returns 405 if the requested method does not exist, otherwise returns 404 handle_options = true # Automatic response OPTIONS request, you can set the default Handler in Faygo no_default_params = false # If true, don't assign default request parameter values based on initial parameter values of the routing handler default_upload = true # Automatically register the default router: /upload/*filepath default_static = true # Automatically register the default router: /static/*filepath [xsrf] # XSRF security section enable = false # Whether enabled or not key = faygoxsrf # Encryption key expire_second = 3600 # Expire of XSRF token [session] # Session section enable = false # Whether enabled or not provider = memory # Data storage name = faygosessionID # The client stores the name of the cookie provider_config = # According to the different engine settings different config information cookie_life_second = 0 # The default value is 0, which is the lifetime of the browser gc_life_second = 300 # The interval between triggering the GC max_life_second = 3600 # The session max lefetime auto_setcookie = true # Automatically set on the session cookie value, the general default true domain = # The domain name that is allowed to access this cookie enable_sid_in_header = false # Whether to write a session ID to the header name_in_header = Faygosessionid # The name of the header when the session ID is written to the header enable_sid_in_urlquery = false # Whether to write the session ID to the URL Query params [apidoc] # API documentation section enable = true # Whether enabled or not path = /apidoc # The URL path nolimit = false # If true, access is not restricted real_ip = false # If true, means verifying the real IP of the visitor whitelist = 192.*|202.122.246.170 # `whitelist=192.*|202.122.246.170` means: only IP addresses that are prefixed with `192.` or equal to `202.122.246.170` are allowed desc = # Description of the application email = # Technician's Email terms_url = # Terms of service license = # The license used by the API license_url = # The URL of the protocol content page
- Only one global config is applied (
config/__global__.ini
). Refer to the following:
[cache] # Cache section enable = false # Whether enabled or not size_mb = 32 # Max size by MB for file cache, the cache size will be set to 512KB at minimum. expire_second = 60 # Maximum duration for caching [gzip] # compression section enable = false # Whether enabled or not min_length = 20 # The minimum length of content to be compressed compress_level = 1 # Non-file response Body's compression level is 0-9, but the files' always 9 methods = GET # List of HTTP methods to compress. If not set, only GET requests are compressed. [log] # Log section console_enable = true # Whether enabled or not console logger console_level = debug # Console logger level: critical | error | warning | notice | info | debug file_enable = true # Whether enabled or not file logger file_level = debug # File logger level: critical | error | warning | notice | info | debug async_len = 0 # The length of asynchronous buffer, 0 means synchronization
tag | key | required | value | desc |
---|---|---|---|---|
param | in | only one | path | (position of param) if required is unsetted, auto set it. e.g. url: "http://www.abc.com/a/{path}" |
param | in | only one | query | (position of param) e.g. url: "http://www.abc.com/a?b={query}" |
param | in | only one | formData | (position of param) e.g. "request body: a=123&b={formData}" |
param | in | only one | body | (position of param) request body can be any content |
param | in | only one | header | (position of param) request header info |
param | in | only one | cookie | (position of param) request cookie info, support: *http.Cookie ,http.Cookie ,string ,[]byte |
param | name | no | (e.g.id ) | specify request param`s name |
param | required | no | request param is required | |
param | desc | no | (e.g.id ) | request param description |
param | len | no | (e.g.3:6 ) | length range [a,b] of param's value |
param | range | no | (e.g.0:10 ) | numerical range [a,b] of param's value |
param | nonzero | no | param`s value can not be zero | |
param | maxmb | no | (e.g.32 ) | when request Content-Type is multipart/form-data, the max memory for body.(multi-param, whichever is greater) |
param | regexp | no | (e.g.^\\w+$ ) | verify the value of the param with a regular expression(param value can not be null) |
param | err | no | (e.g.incorrect password format ) | the custom error for binding or validating |
NOTES:
- the binding object must be a struct pointer
- in addition to
*multipart.FileHeader
, the binding struct's field can not be a pointer - if the
param
tag is not exist, anonymous field will be parsed - when the param's position(
in
) isformData
and the field's type is*multipart.FileHeader
,multipart.FileHeader
,[]*multipart.FileHeader
or[]multipart.FileHeader
, the param receives file uploaded - if param's position(
in
) iscookie
, field's type must be*http.Cookie
orhttp.Cookie
- param tags
in(formData)
andin(body)
can not exist at the same time - there should not be more than one
in(body)
param tag
base | slice | special |
---|---|---|
string | []string | [][]byte |
byte | []byte | [][]uint8 |
uint8 | []uint8 | *multipart.FileHeader (only for formData param) |
bool | []bool | []*multipart.FileHeader (only for formData param) |
int | []int | *http.Cookie (only for net/http 's cookie param) |
int8 | []int8 | http.Cookie (only for net/http 's cookie param) |
int16 | []int16 | struct (struct type only for body param or as an anonymous field to extend params) |
int32 | []int32 | |
int64 | []int64 | |
uint8 | []uint8 | |
uint16 | []uint16 | |
uint32 | []uint32 | |
uint64 | []uint64 | |
float32 | []float32 | |
float64 | []float64 |
package summary | import path |
---|---|
barcode | github.com/andeya/faygo/ext/barcode |
Bit unit conversion | github.com/andeya/faygo/ext/bitconv |
gorm(DB ORM) | github.com/andeya/faygo/ext/db/gorm |
sqlx(DB ext) | github.com/andeya/faygo/ext/db/sqlx |
xorm(DB ORM) | github.com/andeya/faygo/ext/db/xorm |
directSQL(Configured SQL engine) | github.com/andeya/faygo/ext/db/directsql |
One-time Password | github.com/andeya/faygo/ext/otp |
UUID | github.com/andeya/faygo/ext/uuid |
Websocket | github.com/andeya/faygo/ext/websocket |
ini | github.com/andeya/faygo/ini |
cron | github.com/andeya/faygo/ext/cron |
task | github.com/andeya/faygo/ext/task |
http client | github.com/andeya/faygo/ext/surfer |
Product Name | Web/App Server | Home Page |
---|---|---|
盯房 | App | https://www.df-house.com |
eTrade | App | https://fir.im/ejy |
OneFor | App | https://fir.im/eqb |
杰运好车 | App | https://itunes.apple.com/cn/app/%E6%9D%B0%E8%BF%90%E5%A5%BD%E8%BD%A6/id1301132479?mt=8 |
Note: Sorted in alphabetical order
Faygo is under Apache v2 License. See the LICENSE file for the full license text