Faygo 框架

Faygo 使用全新架构,是最合适开发API接口的Go Web框架。用户只需定义一个struct Handler,就能自动绑定、验证请求参数并生成在线API文档。

官方QQ群:Go-Web 编程 42730308

faygo index
faygo apidoc
faygo server

安装要求

Go Version ≥1.8

快速使用

  • 方式一 源码下载
go get -u -v github.com/henrylee2cn/faygo
go get -u -v github.com/henrylee2cn/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 映射
funcstruct
net_typeshttphttpsletsencryptunix_letsencryptunix_httpunix_https
httprouterpongo2gormxormsqlxdirectSQLWebsocketinihttp client
faygo struct handler 多重用途合一

简单示例

package main

import (
    // "mime/multipart"
    "time"
    "github.com/henrylee2cn/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]

扩展包

github.com/henrylee2cn/faygo/ext/barcodegithub.com/henrylee2cn/faygo/ext/bitconvgithub.com/henrylee2cn/faygo/ext/db/gormgithub.com/henrylee2cn/faygo/ext/db/sqlxgithub.com/henrylee2cn/faygo/ext/db/xormgithub.com/henrylee2cn/faygo/ext/db/directsqlgithub.com/henrylee2cn/faygo/ext/otpgithub.com/henrylee2cn/faygo/ext/uuidgithub.com/henrylee2cn/faygo/ext/websocketgithub.com/henrylee2cn/faygo/inigithub.com/henrylee2cn/faygo/ext/crongithub.com/henrylee2cn/faygo/ext/taskgithub.com/henrylee2cn/faygo/ext/surfer

开源协议

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