GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.

GoFrame

Go Doc Build Status Go Report Code Coverage Production Ready License

English | 简体中文

GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang.

If you're a newbie to Go, you may consider GoFrame easy and great as Laravel in PHP, SpringBoot in Java or Django in Python.

Installation

go get -u -v github.com/gogf/gf

suggested using go.mod:

require github.com/gogf/gf latest

Limitation

golang version >= 1.11

Architecture

Packages

  1. Primary Package

    The gf repository maintains some basic and most commonly used packages, keeping it as lightweight and simple as possible.

  2. Community Package

    The community packages are contributed and maintained by community members, which are hosted in gogf organization. Some of the community packages are separated from the gf repository, which are not of common usage or are with heavy dependencies.

Performance

The Web component performance of GoFrame, please refer to third-party project: https://github.com/the-benchmarker/web-frameworks

Documentation

Discussion

It's recommended learning GoFrame through its awesome source codes and API reference.

License

GF is licensed under the MIT License, 100% free and open-source, forever.

Part Of Users

We list part of the users here, if your company or products are using GoFrame, please let us know here.

Contributors

This project exists thanks to all the people who contribute. [Contributors].

Donators

If you love GF, why not buy developer a cup of coffee?

Sponsors

We appreciate any kind of sponsorship for GF development. If you've got some interesting, please contact WeChat 389961817 / Email [email protected].

Thanks

JetBrains Atlassian

Owner
GoFrame
The GoFrame Organization.
GoFrame
Comments
  • 性能问题

    性能问题

    被gf的路由注册、数据库record、自带很多常用的工具集等特点吸引过来,确实方便,花了几天时间打磨出一套快速开发平台,包括权限系统、代码生成的功能,目前也有几个系统在此平台运行。 由于系统涉及到高并发大流量的场景,我做了很多的压测,发现内存不断的增加,3种注册方式都测试过,函数注册、对象注册、控制器注册都试过,甚至函数注册逻辑只渲染一个简单的模板页面,最终结果都会导致内存不断增加,增加到2G之后我就没再做测试,等了数个小时之后,内存才降到200多M。 周末在家,我用gin实现了同样的功能,包括模板输出和json输出,在高并发的情况下,内存稳定在36M。 当然,gin用起来确实没有gf爽快,我希望作者给出内存不断增长的原因。

  • [P0]两点建议,大大有空看到请回复下

    [P0]两点建议,大大有空看到请回复下

    1.关于g.Db,当sql的debug开启时会输出一条条sql日志,目前是这样的

    [ 12 ms] [default] SHOW FULL COLUMNS FROM `users_source 
    

    希望能在链式操作上开放一个接口手动设置一个unique.让其输出变成

    [ 12 ms] [uniquestr] SHOW FULL COLUMNS FROM `users_source` 
    //伪代码:
    db.Table(table).SetUniqueStr(guid.S()).One()
    

    基本每次http请求都会对上下文设置一个workid,让sql日志也实现关联. 2.关于gvalidate.go语言的特性会对数值类型自动设置默认值0,直接导致了required的验证失效,对于数值类型的required验证希望能做成对入参的has+empty+类型验证.例如对如下的money字段验证

    例1:?money=1&uid=1//`p:"money" v:"required " 通过
    例2:?uid=1//`p:"money" v:"required " 不通过
    例3:?money=&uid=1//`p:"money" v:"required " 不通过
    
  • 2.1版本gf build命令没有进行pack打包

    2.1版本gf build命令没有进行pack打包

    2.1版本gf build命令没有进行pack打包

    (1)gf build没有自动执行pack (2)手动pack文件到internal/packed/data.go,然后执行gf build,将编译后的可执行文件在同环境的新设备运行,结果无法运行,原因是manifest和resource的文件找不到。

    config.yaml配置如下

    gfcli:
      build:
        name: "gfCms"
        arch: "amd64"
        system: "linux"
        mod: "none"
        cgo: 0
        pack: "manifest/config,manifest/i18n,resource/public,resource/template"
        version: ""
        output: "./bin"
        extra: ""
    
  • How to develop the doquery method in callback processing on the ORM interface to obtain the request header information of the current request

    How to develop the doquery method in callback processing on the ORM interface to obtain the request header information of the current request

    1. What version of Go and system type/arch are you using?

    go1.16

    2. What version of GoFrame are you using?

    goframe1.16.*

    3. Can this issue be re-produced with the latest release?

    no

    4. What did you do?

    func (d *MyDriver) DoQuery(ctx context.Context, link gdb.Link, sql string, args ...interface{}) (rows *sql.Rows, err error) { r.GetParam("") }

    5. What did you expect to see?

    I want to get the information in the request header of the current request in the callback processing doquery method developed by the ORM interface, because I need to get the tenant in the current request header and then dynamically splice the SQL

    6. What did you see instead?

  • session强制缓存到内存的问题

    session强制缓存到内存的问题

    最近新上服务时发现服务内存使用过多,所以开启了pprof定位,最后定位到是使用了session的问题,从源码可以看到,每次请求结束关闭session时都会把当前session刷进内存且在内存存活的时间与session stroge一致,这样就会导致session的数据会存在两份,一份在远端存储,一份为本地内存。当请求用户基数较大时程序会占用非常大的内存且很久都无法释放 https://github.com/gogf/gf/blob/be77779affcc6b58d9841001c128956aeac750bc/os/gsession/gsession_session.go#L106

    我理解这样设计的原因是当远端session存储不可用时,可以有内存session进行兜底。 但我觉得至少也需要有方法可以限制session使用的内存,遗憾的是目前并没有发现有提供这样的方法 https://github.com/gogf/gf/blob/be77779affcc6b58d9841001c128956aeac750bc/os/gsession/gsession_manager.go#L33

    希望可以在实例化SessionManager的时候设置sessionDatalruCap大小;或者提供可选项,由开发者选择是否使用本地内存缓存session

  • gconv 转换碰到问题

    gconv 转换碰到问题

    1. What version of Go and system type/arch are you using?

    go version go1.13.4 windows/amd64

    2. What version of GoFrame are you using?

    v1.13.2-0.20200701150539-76d93b3a6124

    3. Can this issue be reproduced with the latest release?

    yes

    4. What did you do?

    
    type Sub2 struct {
    	SubName string
    }
    
    type sub1 struct {
    	Sub2
    	Name string
    }
    type Test struct {
    	Sub sub1 `json:"sub"`
    }
    
    func Test_Conv(t *testing.T) {
    	data := `{
        "sub": {
            "Name": "name",
            "SubName": "subname"
        }}`
    	vdata := Test{
    		Sub: sub1{
    			Name: "name",
    			Sub2: Sub2{
    				SubName: "subname",
    			},
    		},
    	}
    	t.Run("gjson.Decode", func(t *testing.T) {
    		tx := Test{}
    		err := gjson.DecodeTo(data, &tx)
    		if err != nil {
    			t.Fatal(err)
    		}
    		gtest.AssertEQ(tx, vdata)
    	})
    	t.Run("gconv.StructDeep", func(t *testing.T) {
    		tx := Test{}
    		err := gconv.StructDeep(data, &tx)
    		if err != nil {
    			t.Fatal(err)
    		}
    		gtest.AssertEQ(tx, vdata)
    	})
    }
    

    如上测试代码

    使用gjson直接转换正常,改成使用gconv转换出来的结果不符合预期?不知是我的使用问题还是BUG?

    原始的使用场景是从配置文件直接转换成所需要的数据格式.发现异常

    g.Cfg().GetStructDeep(name,Point)
    

    目前我的解决方法

    gjson.DecodeTo(g.Cfg().GetString(name), Point)
    

    5. What did you expect to see?

    {"sub":{"SubName":"subname","Name":"name"}}
    

    6. What did you see instead?

    {"sub":{"SubName":"","Name":"name"}}
    
  • 中间件的执行逻辑问题

    中间件的执行逻辑问题

    使用的v1.9.10的GF,现有如下代码:

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gogf/gf/frame/g"
    	"github.com/gogf/gf/net/ghttp"
    )
    
    func MiddlewareAuth1(r *ghttp.Request) {
    	fmt.Println("middleware 1")
    	token := r.Get("token")
    	if token == "123456" {
    		r.Middleware.Next()
    	} else {
    		r.Response.WriteStatus(http.StatusForbidden)
    	}
    }
    func MiddlewareAuth2(r *ghttp.Request) {
    	fmt.Println("middleware 2")
    	token := r.Get("token")
    	if token == "123456" {
    		r.Middleware.Next()
    	} else {
    		r.Response.WriteStatus(http.StatusForbidden)
    	}
    }
    
    func MiddlewareFree(r *ghttp.Request) {
    	fmt.Println("middleware free")
    	r.Response.CORSDefault()
    	r.Middleware.Next()
    }
    func MiddlewareCORS(r *ghttp.Request) {
    	fmt.Println("middleware CORS")
    	r.Response.CORSDefault()
    	r.Middleware.Next()
    }
    
    func main() {
    	s := g.Server()
    	s.Group("/", func(g *ghttp.RouterGroup) {
    		g.MiddlewarePattern("/*", func(r *ghttp.Request) {
    			if r.URL.Path == "/login" {
    				r.Middleware.Next()
    				return
    			}
    			MiddlewareAuth1(r)
    			MiddlewareAuth2(r)
    		})
    	})
    	s.Group("/", func(g *ghttp.RouterGroup) {
    		g.ALL("/login", func(r *ghttp.Request) {
    			r.Response.Write("login")
    		})
    		g.ALL("/dashboard", func(r *ghttp.Request) {
    			r.Response.Write("dashboard")
    		})
    	})
    	s.Group("/api.v2", func(g *ghttp.RouterGroup) {
    		g.Middleware(MiddlewareFree, MiddlewareCORS)
    		g.ALL("/user/list", func(r *ghttp.Request) {
    			r.Response.Write("list")
    		})
    	})
    	s.SetPort(8199)
    	s.Run()
    }
    

    当我请求localhost:8199/api.v2/user/list的时候,的确应该返回403,但是问题是我收到了两个403,响应是这样的:ForbiddenForbidden。我的理解应该是:前一个中间件已经返回403了,不是200了,后面的中间件是不是不要再执行了?或者要其他什么手段控制它是否执行? 如果我把代码改成这样:

    package main
    
    import (
    	"fmt"
    	"net/http"
    
    	"github.com/gogf/gf/frame/g"
    	"github.com/gogf/gf/net/ghttp"
    )
    
    func MiddlewareAuth1(r *ghttp.Request) {
    	fmt.Println("middleware 1")
    	token := r.Get("token")
    	if token == "123456" {
    		r.Middleware.Next()
    	} else {
    		r.Response.WriteStatus(http.StatusForbidden)
    	}
    }
    func MiddlewareAuth2(r *ghttp.Request) {
    	fmt.Println("middleware 2")
    	token := r.Get("token")
    	if token == "123456" {
    		r.Middleware.Next()
    	} else {
    		r.Response.WriteStatus(http.StatusForbidden)
    	}
    }
    
    func MiddlewareFree(r *ghttp.Request) {
    	fmt.Println("middleware free")
    	r.Response.CORSDefault()
    	r.Middleware.Next()
    }
    func MiddlewareCORS(r *ghttp.Request) {
    	fmt.Println("middleware CORS")
    	r.Response.CORSDefault()
    	r.Middleware.Next()
    }
    
    func main() {
    	s := g.Server()
    	s.Group("/", func(g *ghttp.RouterGroup) {
    		g.Middleware(MiddlewareAuth1, MiddlewareAuth2)
    		g.MiddlewarePattern("/*", func(r *ghttp.Request) {
    			if r.URL.Path == "/login" {
    				r.Middleware.Next()
    				return
    			}
    		})
    	})
    	s.Group("/", func(g *ghttp.RouterGroup) {
    		g.ALL("/login", func(r *ghttp.Request) {
    			r.Response.Write("login")
    		})
    		g.ALL("/dashboard", func(r *ghttp.Request) {
    			r.Response.Write("dashboard")
    		})
    	})
    	s.Group("/api.v2", func(g *ghttp.RouterGroup) {
    		g.Middleware(MiddlewareFree, MiddlewareCORS)
    		g.ALL("/user/list", func(r *ghttp.Request) {
    			r.Response.Write("list")
    		})
    	})
    	s.SetPort(8199)
    	s.Run()
    }
    

    注意第44行,是我的改动,此时再请求localhost:8199/api.v2/user/list,只会返回1个403,一个Forbidden,然而,新的问题来了,不能正常访问login接口了。

    总结一下:

    1. 如果使用MiddlewarePattern绑定中间件,前一个403了之后,后一个还会执行,是否bug?
    2. 如果使用RouterGroup绑定中间件,官方文档中的例外控制action就失效了,是否bug?
  • CPU 占用居高不下

    CPU 占用居高不下

    Build Detail: Go Version: go1.13.4 GF Version: v1.13.1 Git Commit: 1db1828b35c15b4a92cd144c33e636eb52d7ec07 Build Time: 2020-06-14 21:01:20

    今日进行代码漏洞扫描,指标如下:

    2个并发请求
    250ms请求延迟
    

    1、持续5分钟后,系统4核CPU全部占满, 2、7分钟后,应用服务响应变慢, 3、扫描结束30分钟后,CPU资源仍未释放

    20201119163428

    profile001

  • Cannot upload file on Linux

    Cannot upload file on Linux

    1. What version of Go and system type/arch are you using?

    go version go1.14.3 linux/amd64

    2. What version of GoFrame are you using?

    v1.12.3

    3. Can this issue be reproduced with the latest release?

    Yes

    4. What did you do?

    Use ghttp client to upload file ghttp.post, although it can be uploaded normally on Windows, it cannot be uploaded on Linux no matter using relative path or absolute path. The file is saved through files.save

    5. What did you expect to see?

    Normal uploads are also available on Linux

    6. What did you see instead?

    Normal uploads are also available on Linux

  • gqueue性能问题咨询

    gqueue性能问题咨询

    最近在使用gf的gqueue的时候,使用日志打点发现gqueue的性能似乎不太稳定,在我理解应该都是毫秒以下的处理,但是实际抖动延时很大,最大的时候达到了140ms,具体如下图描述,是否在使用上存在有什么不对的地方么。 golang 版本 go version go1.11.4 GOOS=linux AMD64 gf 版本 v1.6.17

    TIM截图20190616163435

  • 2.0.6版本自带的swagger不能被其他IP访问

    2.0.6版本自带的swagger不能被其他IP访问

    使用2.0.6版本并配置了swagger,本地打开正常,本地其他ip打开不了,后端显示200

    配置文件 server: address: ":8201" serverRoot: "resource/public" dumpRouterMap: true routeOverWrite: true openapiPath: "/api.json" swaggerPath: "/swagger" NameToUriType: 3 maxHeaderBytes: "20KB" clientMaxBodySize: "50MB"

    Logging配置

    logPath: "resource/log/server" # 日志文件存储目录路径,建议使用绝对路径。默认为空,表示关闭 logStdout: true # 日志是否输出到终端。默认为true errorStack: true # 当Server捕获到异常时是否记录堆栈信息到日志中。默认为true errorLogEnabled: true # 是否记录异常日志信息到日志中。默认为true errorLogPattern: "error-{Ymd}.log" # 异常错误日志文件格式。默认为"error-{Ymd}.log" accessLogEnabled: true # 是否记录访问日志。默认为false accessLogPattern: "access-{Ymd}.log" # 访问日志文件格式。默认为"access-{Ymd}.log"

    访问不了显示 image

    正常访问显示 image

  • 热编译传入args参数时,在windows10下无法正常启动

    热编译传入args参数时,在windows10下无法正常启动

    热编译传入args参数时,在windows10下无法正常启动,但是在linux环境下可以正常使用

    gf版本:v2.2.5

    PS E:\server> gf -v
    GoFrame CLI Tool v2.2.5, https://goframe.org
    GoFrame Version: v2.2.5 in current go.mod
    CLI Installed At: C:\Windows\gf2.exe
    CLI Built Detail:
      Go Version:  go1.17.13
      GF Version:  v2.2.5
      Git Commit:  2022-11-25 10:45:56 4553f90a834ea32ff844303da3f6f18c9f091635
      Build Time:  2022-11-28 20:31:52
    

    代码如下:

    PS E:\server> gf run main.go --args "test"
    build: main.go
    go build -o ./\main.exe  main.go
    ./\main.exe test
    build running error: exec: "E:\\server\\main.exe test": file does not exist
    
  • func RuleGT.Run  always return error

    func RuleGT.Run always return error

    1. What version of Go and system type/arch are you using?

    go 1.19

    2. What version of GoFrame are you using?

    v2.2.5

    3. Can this issue be re-produced with the latest release?

    yes

    4. What did you do?

    I add a valid v:"gt:0" on PageNo

    type GetInspectionTemplateReq struct { g.Meta path:"/inspectionTemplate/get" tags:"InspectionTemplate" method:"post" summary:"GetInspectionTemplate" Name string json:"name" TemplateType int json:"templateType" PeriodType int json:"periodType" Used int json:"used" PageNo int json:"pageNo" v:"gt:0" PageSize int json:"pageSize" v:"gt:0" } Then test the api in postman, the reqest as: { "pageNo":1, "pageSize":10 }

    5. What did you expect to see?

    it return the data from db.

    6. What did you see instead?

    it returns error, "The PageNo" value '1' must be greater than field value ''

  • MYSQL的sleep线程过多,没有复用连接数.

    MYSQL的sleep线程过多,没有复用连接数.

    在gf2.1.4版本下,通过设置 maxIdle: "(可选)连接池最大闲置的连接数" 发现并没有效果

    通过mysql语句查询

    select * from information_schema.processlist 
    

    得到的sleep线程数达到100多

    问题1.该maxIdle设置不是理解上的,空闲时会释放连接池中的连接,只保留设置的数量在连接池中吗?

    问题2.mysql显示的sleep线程越来越多,好像连接池并没有重用一样? maxOpen: "(可选)连接池最大打开的连接数" 没有设置 ps:所有的sleep线程的ip都是同一个,并该ip下只有该进程在运行

    我想要解决? 问题1.希望不要保留太多的空闲连接数

    问题2.希望连接池能重用连接数,因为发现sleep的线程只会越来越多.

  • gconv.Struct方法转换问题

    gconv.Struct方法转换问题

    1. What version of Go and system type/arch are you using?

    go version go1.17.3 darwin/arm64

    2. What version of GoFrame are you using?

    使用了两个版本测试,结果不一样 1、1.16.7 2、2.2.2

    3. Can this issue be re-produced with the latest release?

    4. What did you do?

    func main() {
       var (
          testStruct = struct {
             Time time.Time `json:"time"`
          }{}
          jsonMap = map[string]interface{}{"time": "2022-12-15 16:11:34"}
       )
     
       if err := gconv.Struct(jsonMap, &testStruct); err != nil {
          fmt.Println("gconv.Struct jsonMap失败:", err)
       } else {
          fmt.Println("gconv.Struct jsonMap成功")
       }
     
       // 输出 使用gf v1.16.7结果
       //gconv.Struct jsonMap成功
    
       // 输出 使用gf v2.2.2结果
       //gconv.Struct jsonMap失败: parsing time "2022-12-15 16:11:34" as "2006-01-02T15:04:05Z07:00": cannot parse " 16:11:34" as "T"
    }
    

    5. What did you expect to see?

    从旧版升级到gf2之后,希望gconv.Struct方法是向下兼容的,尤其是对time.Time的转换

    https://github.com/gogf/gf/blob/master/util/gconv/gconv_struct.go#L371 对Common interface check失败后能否再次尝试使用Default converting进行转换

    6. What did you see instead?

  • i18n to translation  multi word not work

    i18n to translation multi word not work

    my code runing in linux amd64 use golang 1.19.3 and gf version v2.2.5 use i18n to translation

    1. zh-CN/vluc.toml "vluc.request" ="请求" "vluc.forbidden"="被禁止的"
    2. test
     i18n := gi18n.New()
      actx := gi18n.WithLanguage(context.TODO(), "zh-CN")
      fmt.Println(i18n.Translate(actx, `{#vluc.request}{#vluc.request}`))
    

    3)output {#vluc.request}{#vluc.request} is not to translate to zh-CN and only use {#vluc.request} also not work but use fmt.Println(i18n.Translate(actx, vluc.request)) is ok 4) it's bug or document error?

Package macaron is a high productive and modular web framework in Go.
Package macaron is a high productive and modular web framework in Go.

Macaron Package macaron is a high productive and modular web framework in Go. Getting Started The minimum requirement of Go is 1.6. To install Macaron

Jan 2, 2023
Mango is a modular web-application framework for Go, inspired by Rack, and PEP333.

Mango Mango is a modular web-application framework for Go, inspired by Rack and PEP333. Note: Not actively maintained. Overview Mango is most of all a

Nov 17, 2022
hiboot is a high performance web and cli application framework with dependency injection support

Hiboot - web/cli application framework About Hiboot is a cloud native web and cli application framework written in Go. Hiboot is not trying to reinven

Nov 20, 2022
A powerful go web framework for highly scalable and resource efficient web application

webfr A powerful go web framework for highly scalable and resource efficient web application Installation: go get -u github.com/krishpranav/webfr Exa

Nov 28, 2021
A powerful go web framework for highly scalable and resource efficient web application

A powerful go web framework for highly scalable and resource efficient web application

Oct 3, 2022
Goal is a toolkit for high productivity web development in Go language in the spirit of Revel Framework that is built around the concept of code generation.

Goal Goal is a set of tools for high productivity web development in Go language. Goal, being mostly inspired by Revel Framework and its discussions,

Sep 27, 2021
A fantastic modular Go web framework boiled with black magic.
A fantastic modular Go web framework boiled with black magic.

A fantastic modular Go web framework boiled with black magic. Getting started The minimum requirement of Go is 1.16. To install Flamego: go get github

Dec 25, 2022
Modular C2 framework aiming to ease post exploitation for red teamers.

test.mp4 testvideo.mp4 Usage: Inside the command server you can reference beacons using either their list id or their unique id. For example if the ou

Dec 17, 2022
GoFarm is an Application Development Framework for especially Backend Developer with Golang

What is GoFarm GoFarm is an Application Development Framework for especially Backend Developer with Golang. Our goal is to develop easier, standardize

Dec 9, 2021
Dragon 🐲 🐲 🐲 is a lightweight high performance web framework with Go for the feature and comfortable develop.

Dragon project new link start dragon ab performance Dragon ?? ?? ?? is a lightweight high performance web framework with Go for the feature and comfor

Sep 6, 2022
Hexya business application development framework

Hexya Hexya is an open source ERP and a business application development framework written in Go. This repository houses the business application deve

Jan 5, 2023
beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 1, 2023
High performance, minimalist Go web framework
High performance, minimalist Go web framework

Supported Go versions As of version 4.0.0, Echo is available as a Go module. Therefore a Go version capable of understanding /vN suffixed imports is r

Jan 2, 2023
Gearbox :gear: is a web framework written in Go with a focus on high performance
Gearbox :gear: is a web framework written in Go with a focus on high performance

gearbox ⚙️ is a web framework for building micro services written in Go with a focus on high performance. It's built on fasthttp which is up to 10x fa

Jan 3, 2023
Gearbox :gear: is a web framework written in Go with a focus on high performance
Gearbox :gear: is a web framework written in Go with a focus on high performance

gearbox ⚙️ is a web framework for building micro services written in Go with a focus on high performance. It's built on fasthttp which is up to 10x fa

Dec 29, 2022
High performance, simple Go web framework

Elton Elton的实现参考了koa以及echo,中间件的调整均为洋葱模型:请求由外至内,响应由内至外。主要特性如下: 处理函数(中间件)均以返回error的形式响应出错,方便使用统一的出错处理中间件将出错统一转换为对应的输出(JSON),并根据出错的类型等生成各类统计分析 成功响应数据直接赋值

Dec 17, 2022
beego is an open-source, high-performance web framework for the Go programming language.
beego is an open-source, high-performance web framework for the Go programming language.

Beego Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. It is inspired by To

Jan 8, 2023
letgo is an open-source, high-performance web framework for the Go programming language.

high-performance Lightweight web framework for the Go programming language. golang web framework,高可用golang web框架,go语言 web框架 ,go web

Sep 23, 2022