Faygo 一款最适合开发 API 的 Go Web 框架

v10yjjngf 8年前
   <h2>Faygo 框架</h2>    <p>Faygo 使用全新架构,是最合适开发API接口的Go Web框架。用户只需定义一个struct Handler,就能自动绑定、验证请求参数并生成在线API文档。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/fe0754a39ae3424edf1a29b9da0ea635.png"></p>    <p>faygo index</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b929670a681068ff48685f04e9c2ef7d.png"></p>    <p>faygo apidoc</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4924199ab7abd7cf10888b1eb497802c.png"></p>    <p>faygo server</p>    <h3>安装要求</h3>    <p>Go Version ≥1.8</p>    <h2>快速使用</h2>    <ul>     <li>方式一 源码下载</li>    </ul>    <pre>  <code class="language-go">go get -u -v github.com/henrylee2cn/faygo</code></pre>    <ul>     <li>方式二 部署工具 ( Go to fay )</li>    </ul>    <pre>  <code class="language-go">go get -u -v github.com/henrylee2cn/fay</code></pre>    <pre>  <code class="language-go">fay command [arguments]    The commands are:          new        创建、编译和运行(监控文件变化)一个新的faygo项目          run        编译和运行(监控文件变化)任意一个已存在的golang项目    fay new appname [apptpl]          appname    指定新faygo项目的创建目录          apptpl     指定一个faygo项目模板(可选)    fay run [appname]          appname    指定待运行的golang项目路径(可选)</code></pre>    <h2>框架特性</h2>    <ul>     <li> <p>一个 struct Handler 搞定多件事:</p>      <ul>       <li>定义 Handler/Middleware</li>       <li>绑定与验证请求参数</li>       <li>生成 Swagger2.0 API 在线文档</li>       <li>数据库 ORM 映射</li>      </ul> </li>     <li> <p>Handler与Middleware完全相同,都是实现Handler接口( func 或 struct 类型),共同构成路由操作链,只是概念层面的说法不同</p> </li>     <li>支持多种网络类型:</li>    </ul>    <table>     <thead>      <tr>       <th>网络类型</th>       <th>配置 net_types 值</th>      </tr>     </thead>     <tbody>      <tr>       <td>HTTP</td>       <td>http</td>      </tr>      <tr>       <td>HTTPS/HTTP2(TLS)</td>       <td>https</td>      </tr>      <tr>       <td>HTTPS/HTTP2(Let's Encrypt TLS)</td>       <td>letsencrypt</td>      </tr>      <tr>       <td>HTTPS/HTTP2(Let's Encrypt TLS on UNIX socket)</td>       <td>unix_letsencrypt</td>      </tr>      <tr>       <td>HTTP(UNIX socket)</td>       <td>unix_http</td>      </tr>      <tr>       <td>HTTPS/HTTP2(TLS on UNIX socket)</td>       <td>unix_https</td>      </tr>     </tbody>    </table>    <ul>     <li>支持单服务单监听、单服务多监听、多服务多监听等,多个服务的配置信息相互独立</li>     <li>基于 httprouter 开发高性能路由,支持链式与树形两种注册风格,支持灵活的静态文件路由(如DirFS、RenderFS、MarkdownFS等)</li>     <li>支持平滑关闭、平滑升级,提供fay工具进行新建项目、热编译、元编程</li>     <li>采用最强大的 pongo2 作为HTML渲染引擎</li>     <li>提供近似LRU的文件缓存功能,主要用途是静态文件缓存</li>     <li>跨平台的彩色日志系统,且同时支持console和file两种输出形式(可以同时使用)</li>     <li>提供Session管理功能</li>     <li>支持Gzip全局配置</li>     <li>提供XSRF跨站请求伪造安全过滤</li>     <li>大多数功能尽量使用简洁的ini进行配置来避免不必要的重新编译,并且这些配置文件支持自动补填默认值</li>     <li>提供 gorm 、 xorm 、 sqlx 、 directSQL 、 Websocket 、 ini 、 http client 等很多常用扩展包</li>    </ul>    <p><img src="https://simg.open-open.com/show/a5ae7e231a8b4bbe53e61dfbbded7f08.png"></p>    <p>faygo struct handler 多重用途合一</p>    <h2>简单示例</h2>    <pre>  <code class="language-go">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"      }  */</code></pre>    <h2>操作和中间件</h2>    <p>操作和中间件是相同的,都是实现了Handler接口!</p>    <ul>     <li>函数类型</li>    </ul>    <pre>  <code class="language-go">// 不含API文档描述  func Page() faygo.HandlerFunc {      return func(ctx *faygo.Context) error {          return ctx.String(200, "faygo")      }  }    // 含API文档描述  var Page2 = faygo.WrapDoc(Page(), "测试页2的注意事项", "文本")</code></pre>    <ul>     <li>结构体类型</li>    </ul>    <pre>  <code class="language-go">// 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",              },          },      }  }</code></pre>    <h2>过滤函数</h2>    <p>过滤函数必须是HandlerFunc类型!</p>    <pre>  <code class="language-go">func Root2Index(ctx *faygo.Context) error {      // 不允许直接访问`/index`      if ctx.Path() == "/index" {          ctx.Stop()          return nil      }      if ctx.Path() == "/" {          ctx.ModifyPath("/index")      }      return nil  }</code></pre>    <h2>路由注册</h2>    <ul>     <li>树状</li>    </ul>    <pre>  <code class="language-go">// 新建应用服务,参数:名称、版本  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",              }),          ),      )</code></pre>    <ul>     <li>链状</li>    </ul>    <pre>  <code class="language-go">// 新建应用服务,参数:名称、版本  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",      })  }</code></pre>    <h2>平滑关闭与重启</h2>    <ul>     <li>平滑关闭</li>    </ul>    <pre>  <code class="language-go">kill [pid]</code></pre>    <ul>     <li>平滑重启</li>    </ul>    <pre>  <code class="language-go">kill -USR2 [pid]</code></pre>    <h2>扩展包</h2>    <table>     <thead>      <tr>       <th>扩展包</th>       <th>导入路径</th>      </tr>     </thead>     <tbody>      <tr>       <td><a href="/misc/goto?guid=4959739068293079600" rel="nofollow,noindex">各种条码</a></td>       <td>github.com/henrylee2cn/faygo/ext/barcode</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068382826658" rel="nofollow,noindex">比特单位</a></td>       <td>github.com/henrylee2cn/faygo/ext/bitconv</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068472668811" rel="nofollow,noindex">gorm数据库引擎</a></td>       <td>github.com/henrylee2cn/faygo/ext/db/gorm</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068555973865" rel="nofollow,noindex">sqlx数据库引擎</a></td>       <td>github.com/henrylee2cn/faygo/ext/db/sqlx</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068626771553" rel="nofollow,noindex">xorm数据库引擎</a></td>       <td>github.com/henrylee2cn/faygo/ext/db/xorm</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068720017584" rel="nofollow,noindex">directSQL(配置化SQL引擎)</a></td>       <td>github.com/henrylee2cn/faygo/ext/db/directsql</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068795853812" rel="nofollow,noindex">口令算法</a></td>       <td>github.com/henrylee2cn/faygo/ext/otp</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068876853617" rel="nofollow,noindex">UUID</a></td>       <td>github.com/henrylee2cn/faygo/ext/uuid</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739068968277296" rel="nofollow,noindex">Websocket</a></td>       <td>github.com/henrylee2cn/faygo/ext/websocket</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739069052816079" rel="nofollow,noindex">ini配置</a></td>       <td>github.com/henrylee2cn/faygo/ini</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739069137895239" rel="nofollow,noindex">定时器</a></td>       <td>github.com/henrylee2cn/faygo/ext/cron</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739069221244976" rel="nofollow,noindex">任务工具</a></td>       <td>github.com/henrylee2cn/faygo/ext/task</td>      </tr>      <tr>       <td><a href="/misc/goto?guid=4959739069298148596" rel="nofollow,noindex">HTTP客户端</a></td>       <td>github.com/henrylee2cn/faygo/ext/surfer</td>      </tr>     </tbody>    </table>    <h2>开源协议</h2>    <p>Faygo 项目采用商业应用友好的 <a href="/misc/goto?guid=4959739069386501256" rel="nofollow,noindex">Apache2.0</a> 协议发布。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/f40b65ccf7a5</p>    <p> </p>