The Good Framework
Gramework long-term testing stand metrics screenshot made with Gramework Stats Dashboard and metrics middleware
If you find it, you can submit vulnerability via [email protected].
Name | Link/Badge |
---|---|
Docs | GoDoc |
Our Jira | Jira |
Support us with a donation or become a sponsor | OpenCollective |
We have #gramework channel in the Gophers Slack | https://gophers.slack.com |
Our Discord Server | https://discord.gg/HkW8DsD |
Master branch coverage | |
Master branch status | |
Dev branch coverage | |
Dev branch status | |
CII Best Practices | |
Gramework Stats Dashboard for Grafana | https://grafana.com/dashboards/3422 |
Fast, highly effective and go-way web framework. You get the simple yet powerful API, we handle optimizations internally. We glad to see your feature requests and PRs, that are implemented as fast as possible while keeping framework high quality. SPA-first, so template engine support is WIP.
Confideal is a service for making fast and safe international deals through smart contracts on Ethereum blockchain.
With Gramework, we have made a number of improvements:
- reduced boilerplate code;
- expedited the development process without cutting neither scope nor performance requirements;
- reduced the code that needs to be maintained;
- saved hundreds of hours by using by using functionality that comes as a part of the framework;
- optimized costs of service maintenance;
- took advantage of services' and the implementation code's being scalable.
Basically, before I've started the project, I need a simple, powerful framework with fair license policy. First I consulted with lawyers, which license to choose, based on the list of packages that I need to use. Next, we discussed what to do in order to do everything as correctly as possible.
In our days, net/http
-based projects are slow and cost-ineffective, so I just write the basic version.
But.
Those support HTTP/2, but theoretically we can make it work even with fasthttp.
Those also support websockets, but this is already was done.
But. Again.
All our company's solutions are based on fasthttp, so we can use our already stable, optimized solutions.
We can provide stable, faster and more effective functionality with really simple API.
We can support net/http
handlers with compatibility layer.
We can support multiple handler signature, allow runtime route registration etc.
And even more We can
.
So - why you may want to use it?
- Gramework is battle-tested
- Gramework is one of the rare frameworks that can help you serve up to 800k rps even on a 4Gb RAM/[email protected]/2x1Gbit server
- Gramework make your projects' infrastructure costs more effective by using as less memory as possible
- Gramework helps you serve requests faster, and so it helps you increase conversions (source 1, source 2)
- You can build software faster with simple API
- You can achieve agile support and get answers to your questions
- You can just ask a feature and most likely it will be implemented and built in
- You can contact me and donate for high priority feature
- You can be sure that all license questions are OK with gramework
- You can buy a corporate-grade support
Stable, but not frozen: we adding functions, packages or optional arguments, so you can use new features, but we never break your projects.
Go >= 1.8 is supported.
Please, fire an issue or pull request if you want any feature, you find a bug or know how to optimize gramework even more.
Using Gramework with dep
is highly recommended.
This project exists thanks to all the people who contribute. [Contribute].
Thank you to all our backers! 🙏 [Become a backer]
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
- Gramework is now powered by fasthttp and custom fasthttprouter, that is embedded now.
You can find licenses in
/3rd-Party Licenses/fasthttp
and/3rd-Party Licenses/fasthttprouter
. - The 3rd autoTLS implementation, placed in
nettls_*.go
, is an integrated version of caddytls, because using it by simple import isn't an option: gramework based onfasthttp
, that is incompatible withnet/http
. In the commit I based on, caddy isApache-2.0
licensed. It's license placed in/3rd-Party Licenses/caddy
. @mholt allow us to copy the code in this repo.
The example below will serve "hello, grameworld". Gramework will register flag "bind" for you, that allows you to choose another ip/port that gramework should listen:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/", "hello, grameworld")
app.ListenAndServe()
}
If you don't want support bind
flag, pass the optional address argument to ListenAndServe
.
NOTE: all examples below will register bind
flag.
From version: 1.1.0-rc1
The example below will serve {"hello":"grameworld"}
from the map. Gramework will register flag "bind" for you, that allows you to choose another ip/port that gramework should listen:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/", func() map[string]interface{} {
return map[string]interface{}{
"hello": "gramework",
}
})
app.ListenAndServe()
}
From version: 1.1.0-rc1
The example below will serve {"hello":"grameworld"}
from the struct. Gramework will register flag "bind" for you, that allows you to choose another ip/port that gramework should listen:
package main
import (
"github.com/gramework/gramework"
)
type SomeResponse struct {
hello string
}
func main() {
app := gramework.New()
app.GET("/", func() interface{} {
return SomeResponse{
hello: "gramework",
}
})
app.ListenAndServe()
}
The example below will serve static files from ./files:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/*any", app.ServeDir("./files"))
app.ListenAndServe()
}
The example below will serve byte slice:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/*any", []byte("some data"))
app.ListenAndServe()
}
The example below will serve JSON:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/someJSON", func(ctx *gramework.Context) {
m := map[string]interface{}{
"name": "Grame",
"age": 20,
}
if err := ctx.JSON(m); err != nil {
ctx.Err500()
}
})
app.ListenAndServe()
}
The example below will serve JSON with CORS enabled for all routes:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.Use(app.CORSMiddleware())
app.GET("/someJSON", func(ctx *gramework.Context) {
m := map[string]interface{}{
"name": "Grame",
"age": 20,
}
if err := ctx.JSON(m); err != nil {
ctx.Err500()
}
})
app.ListenAndServe()
}
The example below will serve JSON with CORS enabled in the handler:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/someJSON", func(ctx *gramework.Context) {
ctx.CORS()
m := map[string]interface{}{
"name": "Grame",
"age": 20,
}
if err := ctx.JSON(m); err != nil {
ctx.Err500()
}
})
app.ListenAndServe()
}
The example below will serve a string:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/someJSON", func(ctx *fasthttp.RequestCtx) {
ctx.WriteString("another data")
})
app.ListenAndServe()
}
The example below shows how you can get fasthttp.RequestCtx from gramework.Context and use it:
package main
import (
"github.com/gramework/gramework"
)
func main() {
app := gramework.New()
app.GET("/someJSON", func(ctx *gramework.Context) {
// same as ctx.WriteString("another data")
ctx.RequestCtx.WriteString("another data")
})
app.ListenAndServe()
}