
Go gives you a fast HTTP server and a good router in Gin, and then leaves every structural decision to you: where models live, how routes are grouped, how a new feature is added without touching the rest. Coming from Django, I missed the answer Django gives to all of that, the app. Gorf is my attempt to bring that structure to Go.
A Gorf project is a set of apps. Each app owns its models, URLs and views in separate files, registers itself with the framework and can be reused in another project by importing it. The framework handles settings, database initialization and route registration. Underneath it is plain Gin, so nothing stops you from dropping down to it.
Features
- Django-style apps with their own models, URLs and views.
- A settings object for secrets and database configuration.
- Pluggable database backends, with SQLite included.
- A ready-made
authapp with JWT support. - Plain Gin underneath, so existing middleware and handlers work unchanged.
If you are new to Go web development, the Gin introduction on this site covers the basics Gorf builds on.
Installation
go get github.com/go-gorf/gorf
Install the optional auth app, which provides user models and JWT login endpoints:
go get github.com/go-gorf/auth
Tutorial
Create a main package. BootstrapRouter is defined in the next step:
package main
import (
"log"
)
func main() {
r := BootstrapRouter()
err := r.Run()
if err != nil {
log.Fatal("Unable to create the gin server")
} // listens on 0.0.0.0:8080
}
Settings
Add settings.go to the same package. It lists the apps, configures the database and secret key and wires everything into a Gin engine. Replace the secret with a value from your environment before deploying; the one below is a placeholder:
package main
import (
"os"
"github.com/gin-gonic/gin"
"github.com/go-gorf/auth"
"github.com/go-gorf/gorf"
)
// add all the apps
var apps = []gorf.GorfApp{
&auth.AuthApp,
}
func LoadSettings() {
// jwt secret key
gorf.Settings.SecretKey = os.Getenv("GORF_SECRET_KEY")
gorf.Settings.DbConf = &gorf.SqliteBackend{
Name: "db.sqlite",
}
}
// bootstrap server
func BootstrapRouter() *gin.Engine {
gorf.Apps = append(apps)
LoadSettings()
gorf.InitializeDatabase()
gorf.SetupApps()
r := gin.Default()
gorf.RegisterApps(r)
return r
}
Write your own app
An app is a Go package with three files. Create a package named hello.
app.go declares the app and its hooks:
package hello
import (
"github.com/go-gorf/gorf"
)
func setup() error {
// Add setup here
return nil
}
var HelloApp = gorf.GorfBaseApp{
Name: "Hello",
RouteHandler: Urls,
SetUpHandler: setup,
}
urls.go maps routes to handlers:
package hello
import "github.com/gin-gonic/gin"
func Urls(r *gin.Engine) {
r.POST("/hello", Hello)
}
views.go holds the handlers:
package hello
import (
"github.com/gin-gonic/gin"
"net/http"
)
func Hello(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"message": "Hello world",
})
}
Add &hello.HelloApp to the apps slice in settings.go, restart, and POST /hello returns the greeting. That is the whole loop: write an app, register it, done.


