{"id":13601099,"url":"https://github.com/andeya/faygo","last_synced_at":"2025-05-15T19:09:02.113Z","repository":{"id":40696643,"uuid":"49730375","full_name":"andeya/faygo","owner":"andeya","description":"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.","archived":false,"fork":false,"pushed_at":"2023-02-25T01:08:06.000Z","size":51685,"stargazers_count":1604,"open_issues_count":8,"forks_count":250,"subscribers_count":104,"default_branch":"master","last_synced_at":"2024-10-29T17:51:19.873Z","etag":null,"topics":["auto-api-doc","golang","hot-update","http2","http2-push","httprouter","middleware","parameter-binding","server","server-push","shutdown-reboot-gracefully","swagger","web-framework"],"latest_commit_sha":null,"homepage":"https://github.com/henrylee2cn/faydoc","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andeya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-01-15T16:21:00.000Z","updated_at":"2024-09-25T04:43:37.000Z","dependencies_parsed_at":"2022-07-08T04:55:00.741Z","dependency_job_id":null,"html_url":"https://github.com/andeya/faygo","commit_stats":{"total_commits":415,"total_committers":15,"mean_commits":"27.666666666666668","dds":"0.11325301204819282","last_synced_commit":"d2a5c3d487358866d1390c32dd00f5122b4a6fc8"},"previous_names":["henrylee2cn/faygo","henrylee2cn/thinkgo"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Ffaygo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Ffaygo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Ffaygo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Ffaygo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andeya","download_url":"https://codeload.github.com/andeya/faygo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254404357,"owners_count":22065641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-api-doc","golang","hot-update","http2","http2-push","httprouter","middleware","parameter-binding","server","server-push","shutdown-reboot-gracefully","swagger","web-framework"],"created_at":"2024-08-01T18:00:55.703Z","updated_at":"2025-05-15T19:09:02.083Z","avatar_url":"https://github.com/andeya.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Faygo [![report card](https://goreportcard.com/badge/github.com/andeya/faygo?style=flat-square)](http://goreportcard.com/report/andeya/faygo) [![github issues](https://img.shields.io/github/issues/andeya/faygo.svg?style=flat-square)](https://github.com/andeya/faygo/issues?q=is%3Aopen+is%3Aissue) [![github closed issues](https://img.shields.io/github/issues-closed-raw/andeya/faygo.svg?style=flat-square)](https://github.com/andeya/faygo/issues?q=is%3Aissue+is%3Aclosed) [![GitHub release](https://img.shields.io/github/release/andeya/faygo.svg?style=flat-square)](https://github.com/andeya/faygo/releases) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/andeya/faygo) [![view Go网络编程群](https://img.shields.io/badge/官方QQ群-Go网络编程(42730308)-27a5ea.svg?style=flat-square)](http://jq.qq.com/?_wv=1027\u0026k=fzi4p1)\r\n\r\n![Faygo Favicon](https://github.com/andeya/faygo/raw/master/doc/faygo_96x96.png)\r\n\r\nFaygo 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 \\\u003cUser Manual\\\u003e](https://github.com/andeya/faydoc)\r\n\r\n[简体中文](https://github.com/andeya/faygo/blob/master/README_ZH.md)\r\n\r\n![faygo index](https://github.com/andeya/faygo/raw/master/doc/index.png)\r\n\r\n![faygo apidoc](https://github.com/andeya/faygo/raw/master/doc/apidoc.png)\r\n\r\n![faygo server](https://github.com/andeya/faygo/raw/master/doc/server.png)\r\n\r\n\r\n## Latest version\r\n\r\n### Version\r\n\r\nv1.2.0\r\n\r\n### Requirements\r\n\r\nGo Version ≥ 1.8\r\n\r\n## Quick Start\r\n\r\n- Way 1: download source\r\n\r\n```sh\r\ngo get -u -v github.com/andeya/faygo\r\n```\r\n\r\n- Way 2: deployment tools ([Go to fay](https://github.com/andeya/fay))\r\n\r\n```sh\r\ngo get -u -v github.com/andeya/fay\r\n```\r\n\r\n```\r\n        fay command [arguments]\r\n\r\nThe commands are:\r\n        new        create, compile and run (monitor changes) a new faygo project\r\n        run        compile and run (monitor changes) an any existing go project\r\n\r\nfay new appname [apptpl]\r\n        appname    specifies the path of the new faygo project\r\n        apptpl     optionally, specifies the faygo project template type\r\n\r\nfay run [appname]\r\n        appname    optionally, specifies the path of the new project\r\n```\r\n\r\n## Features\r\n\r\n- One `struct Handler` can get more things:\r\n * Define Handler/Middleware\r\n * Bind and verify request parameters\r\n * Generate an online document for the Swagger 2.0 API\r\n * Database ORM mapping\r\n\r\n- Handler and Middleware are exactly the same, both implement the Handler interface (`func` or` struct`), which together constitute the handler chain of the router.\r\n- Supports multiple network types:\r\n\r\nNetwork types                                 | Configuration `net_types`\r\n----------------------------------------------|----------------\r\nHTTP                                          | `http`\r\nHTTPS/HTTP2(TLS)                              | `https`\r\nHTTPS/HTTP2(Let's Encrypt TLS)                | `letsencrypt`\r\nHTTPS/HTTP2(Let's Encrypt TLS on UNIX socket) | `unix_letsencrypt`\r\nHTTP(UNIX socket)                             | `unix_http`\r\nHTTPS/HTTP2(TLS on UNIX socket)               | `unix_https`\r\n\r\n- Support single-service \u0026 single-listener, single-service \u0026 multi-listener, multi-service \u0026 multi-listener and so on. The config of multiple services is independent of each other\r\n- 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.)\r\n- Support graceful shutdown and rebooting, provide fay tools which has new projects, hot compilation , meta programming function\r\n- Use the most powerful `pongo2` as the HTML rendering engine\r\n- Support near-LRU memory caching (mainly used for static file cache)\r\n- Support cross-platform color log system, and has two output interface(console and file)\r\n- 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)\r\n- Support global gzip compression config\r\n- Support XSRF security filtering\r\n- Most features try to use simple ini configs to avoid unnecessary recompilation, and these profiles can be automatically assigned default values\r\n- Provide `gorm`, ` xorm`, `sqlx`, ` directSQL`, `Websocket`, ` ini`, `http client` and many other commonly used expansion packages\r\n\r\n![faygo handler multi-usage](https://github.com/andeya/faygo/raw/master/doc/MultiUsage.png)\r\n\r\n## Simple example\r\n\r\n```go\r\npackage main\r\n\r\nimport (\r\n    // \"mime/multipart\"\r\n    \"time\"\r\n    \"github.com/andeya/faygo\"\r\n)\r\n\r\ntype Index struct {\r\n    Id        int      `param:\"\u003cin:path\u003e \u003crequired\u003e \u003cdesc:ID\u003e \u003crange: 0:10\u003e\"`\r\n    Title     string   `param:\"\u003cin:query\u003e \u003cnonzero\u003e\"`\r\n    Paragraph []string `param:\"\u003cin:query\u003e \u003cname:p\u003e \u003clen: 1:10\u003e \u003cregexp: ^[\\\\w]*$\u003e\"`\r\n    Cookie    string   `param:\"\u003cin:cookie\u003e \u003cname:faygoID\u003e\"`\r\n    // Picture         *multipart.FileHeader `param:\"\u003cin:formData\u003e \u003cname:pic\u003e \u003cmaxmb:30\u003e\"`\r\n}\r\n\r\nfunc (i *Index) Serve(ctx *faygo.Context) error {\r\n    if ctx.CookieParam(\"faygoID\") == \"\" {\r\n        ctx.SetCookie(\"faygoID\", time.Now().String())\r\n    }\r\n    return ctx.JSON(200, i)\r\n}\r\n\r\nfunc main() {\r\n    app := faygo.New(\"myapp\", \"0.1\")\r\n\r\n    // Register the route in a chain style\r\n    app.GET(\"/index/:id\", new(Index))\r\n\r\n    // Register the route in a tree style\r\n    // app.Route(\r\n    //     app.NewGET(\"/index/:id\", new(Index)),\r\n    // )\r\n\r\n    // Start the service\r\n    faygo.Run()\r\n}\r\n\r\n/*\r\nhttp GET:\r\n    http://localhost:8080/index/1?title=test\u0026p=abc\u0026p=xyz\r\nresponse:\r\n    {\r\n        \"Id\": 1,\r\n        \"Title\": \"test\",\r\n        \"Paragraph\": [\r\n            \"abc\",\r\n            \"xyz\"\r\n        ],\r\n        \"Cookie\": \"2016-11-13 01:14:40.9038005 +0800 CST\"\r\n    }\r\n*/\r\n```\r\n\r\n[All samples](https://github.com/andeya/faygo/raw/master/samples)\r\n\r\n## Handler and middleware\r\n\r\nHandler and middleware are the same, both implemente Handler interface!\r\n\r\n- function type\r\n\r\n```go\r\n// Page handler doesn't contains API doc description\r\nfunc Page() faygo.HandlerFunc {\r\n    return func(ctx *faygo.Context) error {\r\n        return ctx.String(200, \"faygo\")\r\n    }\r\n}\r\n\r\n// Page2 handler contains API doc description\r\nvar Page2 = faygo.WrapDoc(Page(), \"test page2 notes\", \"test\")\r\n```\r\n\r\n- struct type\r\n\r\n```go\r\n// Param binds and validates the request parameters by Tags\r\ntype Param struct {\r\n    Id    int    `param:\"\u003cin:path\u003e \u003crequired\u003e \u003cdesc:ID\u003e \u003crange: 0:10\u003e\"`\r\n    Title string `param:\"\u003cin:query\u003e\"`\r\n}\r\n\r\n// Serve implemente Handler interface\r\nfunc (p *Param) Serve(ctx *faygo.Context) error {\r\n    return ctx.JSON(200,\r\n        faygo.Map{\r\n            \"Struct Params\":    p,\r\n            \"Additional Param\": ctx.PathParam(\"additional\"),\r\n        }, true)\r\n}\r\n\r\n// Doc implemente API Doc interface (optional)\r\nfunc (p *Param) Doc() faygo.Doc {\r\n    return faygo.Doc{\r\n        // Add the API notes to the API doc\r\n        Note: \"param desc\",\r\n        // declare the response content format to the API doc\r\n        Return: faygo.JSONMsg{\r\n            Code: 1,\r\n            Info: \"success\",\r\n        },\r\n        // additional request parameter declarations to the API doc (optional)\r\n        Params: []faygo.ParamInfo{\r\n            {\r\n                Name:  \"additional\",\r\n                In:    \"path\",\r\n                Model: \"a\",\r\n                Desc:  \"defined by the `Doc()` method\",\r\n            },\r\n        },\r\n    }\r\n}\r\n```\r\n\r\n## Filter function\r\n\r\nThe filter function must be HandleFunc type!\r\n\r\n```go\r\nfunc Root2Index(ctx *faygo.Context) error {\r\n    // Direct access to `/index` is not allowed\r\n    if ctx.Path() == \"/index\" {\r\n        ctx.Stop()\r\n        return nil\r\n    }\r\n    if ctx.Path() == \"/\" {\r\n        ctx.ModifyPath(\"/index\")\r\n    }\r\n    return nil\r\n}\r\n```\r\n\r\n## Route registration\r\n\r\n- tree style\r\n\r\n```go\r\n// New application object, params: name, version\r\nvar app1 = faygo.New(\"myapp1\", \"1.0\")\r\n\r\n// router\r\napp1.Filter(Root2Index).\r\n    Route(\r\n        app1.NewNamedGET(\"test page\", \"/page\", Page()),\r\n        app1.NewNamedGET(\"test page2\", \"/page2\", Page2),\r\n        app1.NewGroup(\"home\",\r\n            app1.NewNamedGET(\"test param\", \"/param\", \u0026Param{\r\n                // sets the default value in the API documentation for the request parameters (optional)\r\n                Id:    1,\r\n                Title: \"test param\",\r\n            }),\r\n        ),\r\n    )\r\n```\r\n\r\n- chain style\r\n\r\n```go\r\n// New application object, params: name, version\r\nvar app2 = faygo.New(\"myapp2\", \"1.0\")\r\n\r\n// router\r\napp2.Filter(Root2Index)\r\napp2.NamedGET(\"test page\", \"/page\", Page())\r\napp2.NamedGET(\"test page2\", \"/page2\", Page2)\r\napp2.Group(\"home\")\r\n{\r\n    app2.NamedGET(\"test param\", \"/param\", \u0026Param{\r\n        // sets the default value in the API documentation for the request parameters(optional)\r\n        Id:    1,\r\n        Title: \"test param\",\r\n    })\r\n}\r\n```\r\n\r\n## Shutdown and reboot\r\n\r\n- shutdown gracefully\r\n\r\n```sh\r\nkill [pid]\r\n```\r\n\r\n- reboot gracefully\r\n\r\n```sh\r\nkill -USR2 [pid]\r\n```\r\n\r\n## Configuration\r\n\r\n- Each instance of the application has a single config (file name format `config/{appname}[_{version}].ini`). Refer to the following:\r\n\r\n```\r\nnet_types              = http|https              # List of network type: http | https | unix_http | unix_https | letsencrypt | unix_letsencrypt\r\naddrs                  = 0.0.0.0:80|0.0.0.0:443  # List of multiple listening addresses\r\ntls_certfile           =                         # TLS certificate file path\r\ntls_keyfile            =                         # TLS key file path\r\nletsencrypt_dir        =                         # Let's Encrypt TLS certificate cache directory\r\nunix_filemode          = 0666                    # File permissions for UNIX listener, requires octal number\r\nhttp_redirect_https    = false                   # Redirect from 'http://hostname:port1' to 'https://hostname:port2'\r\nread_timeout           = 0s                      # Maximum duration for reading the full; ns|µs|ms|s|m|h request (including body)\r\nwrite_timeout          = 0s                      # Maximum duration for writing the full; ns|µs|ms|s|m|h response (including body)\r\nmultipart_maxmemory_mb = 32                      # Maximum size of memory that can be used when receiving uploaded files\r\nslow_response_threshold= 0s                      # When response time \u003e slow_response_threshold, log level   = 'WARNING'; 0 means not limited; ns|µs|ms|s|m|h\r\nprint_body             = false                   # Form requests are printed in JSON format, but other types are printed as-is\r\n\r\n[router]                                         # Routing config section\r\nredirect_trailing_slash   = true                 # Automatic redirection (for example, `/foo/` -\u003e `/foo`)\r\nredirect_fixed_path       = true                 # Tries to fix the current request path, if no handle is registered for it\r\nhandle_method_not_allowed = true                 # Returns 405 if the requested method does not exist, otherwise returns 404\r\nhandle_options            = true                 # Automatic response OPTIONS request, you can set the default Handler in Faygo\r\nno_default_params         = false                # If true, don't assign default request parameter values based on initial parameter values of the routing handler\r\ndefault_upload            = true                 # Automatically register the default router: /upload/*filepath\r\ndefault_static            = true                 # Automatically register the default router: /static/*filepath\r\n\r\n[xsrf]                                           # XSRF security section\r\nenable        = false                            # Whether enabled or not\r\nkey           = faygoxsrf                        # Encryption key\r\nexpire_second = 3600                             # Expire of XSRF token\r\n\r\n[session]                                        # Session section\r\nenable                 = false                   # Whether enabled or not\r\nprovider               = memory                  # Data storage\r\nname                   = faygosessionID          # The client stores the name of the cookie\r\nprovider_config        =                         # According to the different engine settings different config information\r\ncookie_life_second     = 0                       # The default value is 0, which is the lifetime of the browser\r\ngc_life_second         = 300                     # The interval between triggering the GC\r\nmax_life_second        = 3600                    # The session max lefetime\r\nauto_setcookie         = true                    # Automatically set on the session cookie value, the general default true\r\ndomain                 =                         # The domain name that is allowed to access this cookie\r\nenable_sid_in_header   = false                   # Whether to write a session ID to the header\r\nname_in_header         = Faygosessionid          # The name of the header when the session ID is written to the header\r\nenable_sid_in_urlquery = false                   # Whether to write the session ID to the URL Query params\r\n\r\n[apidoc]                                         # API documentation section\r\nenable      = true                               # Whether enabled or not\r\npath        = /apidoc                            # The URL path\r\nnolimit     = false                              # If true, access is not restricted\r\nreal_ip     = false                              # If true, means verifying the real IP of the visitor\r\nwhitelist   = 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\r\ndesc        =                                    # Description of the application\r\nemail       =                                    # Technician's Email\r\nterms_url   =                                    # Terms of service\r\nlicense     =                                    # The license used by the API\r\nlicense_url =                                    # The URL of the protocol content page\r\n```\r\n\r\n- Only one global config is applied (`config/__global__.ini`). Refer to the following:\r\n\r\n```\r\n[cache]                                          # Cache section\r\nenable         = false                           # Whether enabled or not\r\nsize_mb        = 32                              # Max size by MB for file cache, the cache size will be set to 512KB at minimum.\r\nexpire_second  = 60                              # Maximum duration for caching\r\n\r\n[gzip]                                           # compression section\r\nenable         = false                           # Whether enabled or not\r\nmin_length     = 20                              # The minimum length of content to be compressed\r\ncompress_level = 1                               # Non-file response Body's compression level is 0-9, but the files' always 9\r\nmethods        = GET                             # List of HTTP methods to compress. If not set, only GET requests are compressed.\r\n\r\n[log]                                            # Log section\r\nconsole_enable = true                            # Whether enabled or not console logger\r\nconsole_level  = debug                           # Console logger level: critical | error | warning | notice | info | debug\r\nfile_enable    = true                            # Whether enabled or not file logger\r\nfile_level     = debug                           # File logger level: critical | error | warning | notice | info | debug\r\nasync_len      = 0                               # The length of asynchronous buffer, 0 means synchronization\r\n```\r\n\r\n## Handler struct tags\r\n\r\ntag   |   key    | required |     value     |   desc\r\n------|----------|----------|---------------|----------------------------------\r\nparam |    in    | only one |     path      | (position of param) if `required` is unsetted, auto set it. e.g. url: \"http://www.abc.com/a/{path}\"\r\nparam |    in    | only one |     query     | (position of param) e.g. url: \"http://www.abc.com/a?b={query}\"\r\nparam |    in    | only one |     formData  | (position of param) e.g. \"request body: a=123\u0026b={formData}\"\r\nparam |    in    | only one |     body      | (position of param) request body can be any content\r\nparam |    in    | only one |     header    | (position of param) request header info\r\nparam |    in    | only one |     cookie    | (position of param) request cookie info, support: `*http.Cookie`,`http.Cookie`,`string`,`[]byte`\r\nparam |   name   |    no    |   (e.g.`id`)   | specify request param`s name\r\nparam | required |    no    |               | request param is required\r\nparam |   desc   |    no    |   (e.g.`id`)   | request param description\r\nparam |   len    |    no    | (e.g.`3:6`) | length range [a,b] of param's value\r\nparam |   range  |    no    |  (e.g.`0:10`)  | numerical range [a,b] of param's value\r\nparam |  nonzero |    no    |               | param`s value can not be zero\r\nparam |   maxmb  |    no    |   (e.g.`32`)   | when request Content-Type is multipart/form-data, the max memory for body.(multi-param, whichever is greater)\r\nparam |  regexp  |    no    | (e.g.`^\\\\w+$`) | verify the value of the param with a regular expression(param value can not be null)\r\nparam |   err    |    no    |(e.g.`incorrect password format`)| the custom error for binding or validating\r\n\r\n**NOTES**:\r\n* the binding object must be a struct pointer\r\n* in addition to `*multipart.FileHeader`, the binding struct's field can not be a pointer\r\n* if the `param` tag is not exist, anonymous field will be parsed\r\n* when the param's position(`in`) is `formData` and the field's type is `*multipart.FileHeader`, `multipart.FileHeader`, `[]*multipart.FileHeader` or `[]multipart.FileHeader`, the param receives file uploaded\r\n* if param's position(`in`) is `cookie`, field's type must be `*http.Cookie` or `http.Cookie`\r\n* param tags `in(formData)` and `in(body)` can not exist at the same time\r\n* there should not be more than one `in(body)` param tag\r\n\r\n## Handler struct fields type\r\n\r\nbase    |   slice    | special\r\n--------|------------|-------------------------------------------------------\r\nstring  |  []string  | [][]byte\r\nbyte    |  []byte    | [][]uint8\r\nuint8   |  []uint8   | *multipart.FileHeader (only for `formData` param)\r\nbool    |  []bool    | []*multipart.FileHeader (only for `formData` param)\r\nint     |  []int     | *http.Cookie (only for `net/http`'s `cookie` param)\r\nint8    |  []int8    | http.Cookie (only for `net/http`'s `cookie` param)\r\nint16   |  []int16   | struct (struct type only for `body` param or as an anonymous field to extend params)\r\nint32   |  []int32   |\r\nint64   |  []int64   |\r\nuint8   |  []uint8   |\r\nuint16  |  []uint16  |\r\nuint32  |  []uint32  |\r\nuint64  |  []uint64  |\r\nfloat32 |  []float32 |\r\nfloat64 |  []float64 |\r\n\r\n## Expansion package\r\n\r\npackage summary  |  import path\r\n-----------------|-----------------------------------------------------------------------------------------------------------------\r\n[barcode](https://github.com/andeya/faygo/raw/master/ext/barcode)             | `github.com/andeya/faygo/ext/barcode`\r\n[Bit unit conversion](https://github.com/andeya/faygo/raw/master/ext/bitconv) | `github.com/andeya/faygo/ext/bitconv`\r\n[gorm(DB ORM)](https://github.com/andeya/faygo/raw/master/ext/db/gorm)        | `github.com/andeya/faygo/ext/db/gorm`\r\n[sqlx(DB ext)](https://github.com/andeya/faygo/raw/master/ext/db/sqlx)        | `github.com/andeya/faygo/ext/db/sqlx`\r\n[xorm(DB ORM)](https://github.com/andeya/faygo/raw/master/ext/db/xorm)        | `github.com/andeya/faygo/ext/db/xorm`\r\n[directSQL(Configured SQL engine)](https://github.com/andeya/faygo/raw/master/ext/db/directsql) | `github.com/andeya/faygo/ext/db/directsql`\r\n[One-time Password](https://github.com/andeya/faygo/raw/master/ext/otp)       | `github.com/andeya/faygo/ext/otp`\r\n[UUID](https://github.com/andeya/faygo/raw/master/ext/uuid)                   | `github.com/andeya/faygo/ext/uuid`\r\n[Websocket](https://github.com/andeya/faygo/raw/master/ext/websocket)         | `github.com/andeya/faygo/ext/websocket`\r\n[ini](https://github.com/andeya/faygo/raw/master/ini)                         | `github.com/andeya/faygo/ini`\r\n[cron](https://github.com/andeya/faygo/raw/master/ext/cron)                   | `github.com/andeya/faygo/ext/cron`\r\n[task](https://github.com/andeya/faygo/raw/master/ext/task)                   | `github.com/andeya/faygo/ext/task`\r\n[http client](https://github.com/andeya/faygo/raw/master/ext/surfer)          | `github.com/andeya/faygo/ext/surfer`\r\n\r\n\r\n## Know Cases\r\n\r\nProduct Name     | Web/App Server | Home Page\r\n-----------------|----------------|-----------------\r\n盯房              | App           | https://www.df-house.com\r\neTrade           | App           | https://fir.im/ejy\r\nOneFor           | App           | https://fir.im/eqb\r\n杰运好车          | App            | https://itunes.apple.com/cn/app/%E6%9D%B0%E8%BF%90%E5%A5%BD%E8%BD%A6/id1301132479?mt=8\r\n\r\n*Note: Sorted in alphabetical order*\r\n\r\n## Business Users\r\n\r\n\u003ca href=\"https://tech.pingan.com/index.html\" style=\"margin-right: -120px\"\u003e\u003cimg src=\"http://pa-tech.hirede.com/templates/pa-tech/Images/logo.png\" height=\"50\" width=\"406\" alt=\"平安科技\"/\u003e\u003c/a\u003e\r\n\u0026nbsp;\u0026nbsp;\r\n\u003ca href=\"https://www.followme.cn/\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/andeya/imgs-repo/master/followme.png\" height=\"60\" alt=\"Followme\"/\u003e\u003c/a\u003e\r\n\u003cbr/\u003e\r\n\u003ca href=\"https://www.df-house.com/\"\u003e\u003cimg src=\"https://www.df-house.com/dfhouse/img/logo.png\" height=\"50\" alt=\"杭州盯房科技有限公司\"/\u003e\u003c/a\u003e\r\n\u0026nbsp;\u0026nbsp;\r\n\u003ca href=\"http://www.zlgjjt.com/\" style=\"background-color:block\"\u003e\u003cimg src=\"http://company.zhaopin.com/CompanyLogo/20160314/524FDDEA17D14FAEB704AD40E5179988.jpg\" height=\"70\" alt=\"众联网游\"/\u003e\u003c/a\u003e\r\n\u0026nbsp;\u0026nbsp;\r\n\u003ca href=\"https://www.phonelee.com/\"\u003e\u003cimg src=\"http://company.zhaopin.com/CompanyLogo/20170522/1DE0ABD220F1C4A253751F78B35E32F4.jpg\" height=\"70\" alt=\"丰利金服\"/\u003e\u003c/a\u003e\r\n\r\n## License\r\n\r\nFaygo is under Apache v2 License. See the [LICENSE](https://github.com/andeya/faygo/raw/master/LICENSE) file for the full license text\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Ffaygo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandeya%2Ffaygo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Ffaygo/lists"}