Skip to content

Latest commit

 

History

History
455 lines (368 loc) · 20.8 KB

README_ZH.md

File metadata and controls

455 lines (368 loc) · 20.8 KB

Faygo report card github issues github closed issues GitHub release GoDoc view Go网络编程群

Faygo Favicon

Faygo 是一款快速、简洁的Go Web框架,可用极少的代码开发出高性能的Web应用程序(尤其是API接口)。只需定义 struct Handler,Faygo 就能自动绑定、验证请求参数并生成在线API文档。

查看《用户手册》

faygo index

faygo apidoc

faygo server

最新版本

版本号

v1.2.0

安装要求

Go Version ≥ 1.8

快速使用

  • 方式一 源码下载
go get -u -v github.com/andeya/faygo
go get -u -v github.com/andeya/fay
        fay command [arguments]

The commands are:
        new        创建、编译和运行(监控文件变化)一个新的faygo项目
        run        编译和运行(监控文件变化)任意一个已存在的golang项目

fay new appname [apptpl]
        appname    指定新faygo项目的创建目录
        apptpl     指定一个faygo项目模板(可选)

fay run [appname]
        appname    指定待运行的golang项目路径(可选)

框架特性

  • 一个 struct Handler 搞定多件事:
  • 定义 Handler/Middleware
  • 绑定与验证请求参数
  • 生成 Swagger2.0 API 在线文档
  • 数据库 ORM 映射
  • Handler与Middleware完全相同,都是实现Handler接口(funcstruct类型),共同构成路由操作链,只是概念层面的说法不同
  • 支持多种网络类型:
网络类型 配置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
  • 支持单服务单监听、单服务多监听、多服务多监听等,多个服务的配置信息相互独立
  • 基于 httprouter 开发高性能路由,支持链式与树形两种注册风格,支持灵活的静态文件路由(如DirFS、RenderFS、MarkdownFS等)
  • 支持平滑关闭、平滑升级,提供fay工具进行新建项目、热编译、元编程
  • 采用最强大的 pongo2 作为HTML渲染引擎
  • 提供近似LRU的文件缓存功能,主要用途是静态文件缓存
  • 跨平台的彩色日志系统,且同时支持console和file两种输出形式(可以同时使用)
  • 提供Session管理功能(如使用持久化存储引擎,须在启动服务前使用gob.Register()注册相关的自定义类型)
  • 支持Gzip全局配置
  • 提供XSRF跨站请求伪造安全过滤
  • 大多数功能尽量使用简洁的ini进行配置来避免不必要的重新编译,并且这些配置文件支持自动补填默认值
  • 提供 gormxormsqlxdirectSQLWebsocketinihttp client 等很多常用扩展包

faygo struct handler 多重用途合一

简单示例

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接口!

  • 函数类型
// 不含API文档描述
func Page() faygo.HandlerFunc {
    return func(ctx *faygo.Context) error {
        return ctx.String(200, "faygo")
    }
}

// 含API文档描述
var Page2 = faygo.WrapDoc(Page(), "测试页2的注意事项", "文本")
  • 结构体类型
// Param操作通过Tag绑定并验证请求参数
type Param struct {
    Id    int    `param:"<in:path> <required> <desc:ID> <range: 0:10>"`
    Title string `param:"<in:query>"`
}

// Serve实现Handler接口
func (p *Param) Serve(ctx *faygo.Context) error {
    return ctx.JSON(200,
        faygo.Map{
            "Struct Params":    p,
            "Additional Param": ctx.PathParam("additional"),
        }, true)
}

// Doc实现API文档接口(可选)
func (p *Param) Doc() faygo.Doc {
    return faygo.Doc{
        // 向API文档声明接口注意事项
        Note: "param desc",
        // 向API文档声明响应内容格式
        Return: faygo.JSONMsg{
            Code: 1,
            Info: "success",
        },
        // 向API文档增加额外的请求参数声明(可选)
        Params: []faygo.ParamInfo{
            {
                Name:  "additional",
                In:    "path",
                Model: "a",
                Desc:  "defined by the `Doc()` method",
            },
        },
    }
}

过滤函数

过滤函数必须是HandlerFunc类型!

func Root2Index(ctx *faygo.Context) error {
    // 不允许直接访问`/index`
    if ctx.Path() == "/index" {
        ctx.Stop()
        return nil
    }
    if ctx.Path() == "/" {
        ctx.ModifyPath("/index")
    }
    return nil
}

路由注册

  • 树状
// 新建应用服务,参数:名称、版本
var app1 = faygo.New("myapp1", "1.0")

// 路由
app1.Filter(Root2Index).
    Route(
        app1.NewNamedGET("测试页1", "/page", Page()),
        app1.NewNamedGET("测试页2", "/page2", Page2),
        app1.NewGroup("home",
            app1.NewNamedGET("test param", "/param", &Param{
                // 为绑定的参数设定API文档中缺省值(可选)
                Id:    1,
                Title: "test param",
            }),
        ),
    )
  • 链状
// 新建应用服务,参数:名称、版本
var app2 = faygo.New("myapp2", "1.0")

// 路由
app2.Filter(Root2Index)
app2.NamedGET("test page", "/page", Page())
app2.NamedGET("test page2", "/page2", Page2)
app2.Group("home")
{
    app2.NamedGET("test param", "/param", &Param{
        // 为绑定的参数设定API文档中缺省值(可选)
        Id:    1,
        Title: "test param",
    })
}

平滑关闭与重启

  • 平滑关闭
kill [pid]
  • 平滑重启
kill -USR2 [pid]

配置文件说明

  • 应用的各服务均有单独一份配置,其文件名格式 config/{appname}[_{version}].ini,配置详情:
net_types              = http|https              # 多种网络类型列表,支持 http | https | unix_http | unix_https | letsencrypt | unix_letsencrypt
addrs                  = 0.0.0.0:80|0.0.0.0:443  # 多个监听地址列表
tls_certfile           =                         # TLS证书文件路径
tls_keyfile            =                         # TLS密钥文件路径
letsencrypt_dir        =                         # Let's Encrypt TLS证书缓存目录
unix_filemode          = 0666                    # UNIX listener的文件权限,要求使用八进制
http_redirect_https    = false                   # 从 'http://hostname:port1' 重定向到 'https://hostname:port2'
read_timeout           = 0s                      # 读取请求数据超时;ns|µs|ms|s|m|h
write_timeout          = 0s                      # 写入响应数据超时;ns|µs|ms|s|m|h
multipart_maxmemory_mb = 32                      # 接收上传文件时允许使用的最大内存
slow_response_threshold= 0s                      # 当响应时长 > slow_response_threshold时, 日志级别调整为 'WARNING';0 表示不限;ns|µs|ms|s|m|h
print_body             = false                   # 以JSON格式打印表单请求的body,其它类型请求原样打印body

[router]                                         # 路由配置区
redirect_trailing_slash   = true                 # 当前请求的URL含`/`后缀如`/foo/`且相应路由不存在时,如存在`/foo`,则自动跳转至`/foo`
redirect_fixed_path       = true                 # 自动修复URL,如`/FOO` `/..//Foo`均被跳转至`/foo`(依赖redirect_trailing_slash=true)
handle_method_not_allowed = true                 # 若开启,当前请求方法不存在时返回405,否则返回404
handle_options            = true                 # 若开启,自动应答OPTIONS类请求,可在Faygo中设置默认Handler
no_default_params         = false                # 若开启,不使用handler参数初始值作为请求参数默认值
default_upload            = true                 # 自动注册默认静态路由: /upload/*filepath
default_static            = true                 # 自动注册默认静态路由: /static/*filepath

[xsrf]                                           # XSRF跨站请求伪造过滤配置区
enable        = false                            # 是否开启
key           = faygoxsrf                        # 加密key
expire_second = 3600                             # xsrf防伪token有效时长

[session]                                        # Session配置区(详情参考beego session模块)
enable                 = false                   # 是否开启
provider               = memory                  # 数据存储方式
name                   = faygosessionID        # 客户端存储cookie的名字
provider_config        =                         # 配置信息,根据不同的引擎设置不同的配置信息
cookie_life_second     = 0                       # 客户端存储的cookie的时间,默认值是0,即浏览器生命周期
gc_life_second         = 300                     # 触发GC的时间
max_life_second        = 3600                    # 会话的最大生命周期
auto_setcookie         = true                    # 是否自动设置关于session的cookie值,一般默认true
domain                 =                         # 可以访问此cookie的域名
enable_sid_in_header   = false                   # 是否将session ID写入Header
name_in_header         = Faygosessionid        # 将session ID写入Header时的头名称
enable_sid_in_urlquery = false                   # 是否将session ID写入url的query部分

[apidoc]                                         # API文档
enable      = true                               # 是否启用
path        = /apidoc                            # 访问的URL路径
nolimit     = false                              # 是否不限访问IP
real_ip     = false                              # 使用真实客户端的IP进行过滤
whitelist   = 192.*|202.122.246.170              # 表示允许带有`192.`前缀或等于`202.122.246.170`的IP访问
desc        =                                    # 项目描述
email       =                                    # 联系人邮箱
terms_url   =                                    # 服务条款URL
license     =                                    # 协议类型
license_url =                                    # 协议内容URL
  • 应用只有一份全局配置,文件名为 config/__global__.ini,配置详情:
[cache]                                          # 文件内存缓存配置区
enable         = false                           # 是否开启
size_mb        = 32                              # 允许缓存使用的最大内存(单位MB),为0时系统自动设置为512KB
expire_second  = 60                              # 缓存最大时长

[gzip]                                           # gzip压缩配置区
enable         = false                           # 是否开启
min_length     = 20                              # 进行压缩的最小内容长度
compress_level = 1                               # 非文件类响应Body的压缩水平(0-9),注意文件压缩始终为最优压缩比(9)
methods        = GET                             # 允许压缩的请求方法,为空时默认为GET

[log]                                            # 日志配置区
console_enable = true                            # 是否启用控制台日志
console_level  = debug                           # 控制台日志打印水平:critical | error | warning | notice | info | debug
file_enable    = true                            # 是否启用文件日志
file_level     = debug                           # 文件日志打印水平:critical | error | warning | notice | info | debug
async_len      = 0                               # 0表示同步打印,大于0表示异步缓存长度

Handler结构体字段标签说明

tag key required value desc
param in 有且只有一个 path (参数位置)为空时自动补全,如URL http://www.abc.com/a/{path}
param in 有且只有一个 query (参数位置)如URL http://www.abc.com/a?b={query}
param in 有且只有一个 formData (参数位置)请求表单,如 a=123&b={formData}
param in 有且只有一个 body (参数位置)请求Body
param in 有且只有一个 header (参数位置)请求头
param in 有且只有一个 cookie (参数位置)请求cookie,支持:*http.Cookiehttp.Cookiestring[]byte
param name (如id) 自定义参数名
param required required 参数是否必须
param desc (如id) 参数描述
param len (如3:6) 字符串类型参数的长度范围[a,b]
param range (如0:10) 数字类型参数的数值范围[a,b]
param nonzero nonzero 是否能为零值
param maxmb (如32) 当前Content-Typemultipart/form-data时,允许使用的最大内存,当设置了多个时使用较大值
param regexp (如^\w+$) 使用正则验证参数值
param err (如密码格式错误) 自定义参数绑定或验证的错误信息

NOTES:

  • 绑定的对象必须为结构体指针类型
  • *multipart.FileHeader外,绑定的结构体字段类型不能为指针类型
  • param标签不存在,将尝试解析匿名字段
  • 当结构体标签informData且字段类型为*multipart.FileHeadermultipart.FileHeader[]*multipart.FileHeader[]multipart.FileHeader时,该参数接收文件类型
  • 当结构体标签incookie,字段类型必须为*http.Cookiehttp.Cookie
  • 标签in(formData)in(body)不能同时出现在同一结构体
  • 不能存在多个in(body)标签

Handler结构体字段类型说明

base slice special
string []string [][]byte
byte []byte [][]uint8
uint8 []uint8 *multipart.FileHeader (仅formData参数使用)
bool []bool []*multipart.FileHeader (仅formData参数使用)
int []int *http.Cookie (仅net/http下的cookie参数使用)
int8 []int8 http.Cookie (仅net/http下的cookie参数使用)
int16 []int16 struct (body参数使用或用于匿名字段扩展参数)
int32 []int32
int64 []int64
uint8 []uint8
uint16 []uint16
uint32 []uint32
uint64 []uint64
float32 []float32
float64 []float64

扩展包

扩展包 导入路径
各种条码 github.com/andeya/faygo/ext/barcode
比特单位 github.com/andeya/faygo/ext/bitconv
gorm数据库引擎 github.com/andeya/faygo/ext/db/gorm
sqlx数据库引擎 github.com/andeya/faygo/ext/db/sqlx
xorm数据库引擎 github.com/andeya/faygo/ext/db/xorm
directSQL(配置化SQL引擎) github.com/andeya/faygo/ext/db/directsql
口令算法 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
定时器 github.com/andeya/faygo/ext/cron
任务工具 github.com/andeya/faygo/ext/task
HTTP客户端 github.com/andeya/faygo/ext/surfer

已知案例

产品名称 Web/App 服务器 主页
盯房 App https://www.df-house.com
e交易 App https://fir.im/ejy
玩付 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

注:按拼音字母排序

企业用户

平安科技    Followme
杭州盯房科技有限公司    众联网游    丰利金服

开源协议

Faygo 项目采用商业应用友好的 Apache2.0 协议发布