A Go http wrapper for quick development.
- Kinda extensible
- Session management
- Resource management
- Questionable caching
- One dependency
Internally, there is also:
- Documentation on how things work and are implemented /contributor-docs
Testing suitehmmmmmm
There are probably better wrappers out there. Heck, even better Go web server implementations. And faster, too. This project was started to move from Python (Flask) to Go, but no suitable replacement was found. Therefore, it was decided to make our own, because reinventing the wheel is always such a good and well-thought-out decision™
There are docstrings everywhere, and if you want to contribute you should check out our contributor documentation. Otherwise, here's a quick introduction.
Every route handler is a function. It gets a Request and returns a Response. Compass takes
that Response and does the actual writing to the client, so you never touch http.ResponseWriter.
func handleHello(r compass.Request) compass.Response {
return compass.Text("hello")
}compass.Text("hello") builds a response value, and Compass does the rest, just like Flask.
server := compass.NewServer(compass.NewStandardConfiguration())
server.AddRoute("/", func (r compass.Request) compass.Response {
return compass.Text("hello")
})
server.MustRun() // listens on :3000NewStandardConfiguration() defaults:
| Option | Default | Note |
|---|---|---|
Port |
3000 |
|
AssetDir |
"assets" |
root for static files |
StaticUrl |
"/static" |
URL prefix for static files |
CompassDir |
".compass" |
where sessions and other state are stored |
SessionExpiryTime |
259200000 |
ms; 72 hours |
SessionTickInterval |
300000 |
ms; how often we check for session expiry |
You can also dump or load the config struct in JSON, because the configuration has corresponding field tags.
Wrap a segment in < > to make it a parameter:
server.AddRoute("/users/<id>", func (r compass.Request) compass.Response {
id, _ := r.GetRouteParam("id")
return compass.Text("user: " + id)
})Routes accept GET only by default. Change that on the returned route:
server.AddRoute("/items", handler).AllowedMethods = []string{"get", "post"}compass.Text("hello") // 200, just text
compass.TextWithCode("nope", 403) // any status
compass.HTML("<p>hiii</p>") // 200, displayed as HTML
compass.JsonMarshal(myStruct) // marshals to JSON, 200
compass.Redirect("/login", false) // 303 redirect
compass.DownloadFile("report.pdf", path) // triggers a file download
compass.ServeFile(path, "photo.jpg") // serves pictureHeaders and cookies go directly on the response value:
resp := compass.JsonMarshal(data)
resp.Headers["X-Request-Id"] = "abc"
resp.SetCookie(compass.Cookie{Name: "theme", Value: "light"})
return respAnything in assets/static/ is served under /static/ automatically. Both paths are
configurable.
Compass does not come with its own templating engine. We recommend using something like
fasttemplate and serving its output as text. It is
recommended, but not required, to put your templates in the assets/templates/ directory. This
is up to you.
Sessions are stored as JSON files in .compass/session/, so they survive restarts.
session, err := server.CreateSession()
resp := compass.Redirect("/", false)
resp.SetSession(session)
return resp
// get it back on the next request
session, ok := r.GetSession(server)
// read a value
name, err := compass.SessionGet[string](session, "name")
pfpLink := compass.SessionGetOrDefault[string](session, "profilePicture", "/static/default.png")
// write a value
tx := session.BeginTx()
tx.Set("name", "alice")
tx.Commit()return compass.JsonMarshal(data).WithCORS(compass.AllowAll())AllowAll() is wide open, which is fine locally, but probably not for production. For production,
set only what you need:
policy := compass.CORSPolicy{Origin: "https://example.com", Methods: []string{"get", "post"}}
return compass.Text("I'm a very secretive text!").WithCORS(policy)server.NotFoundHandler = func(r compass.Request) compass.Response {
return compass.TextWithCode("not found", 404)
}
server.MethodNotAllowedHandler = func(r compass.Request) compass.Response {
return compass.TextWithCode("method not allowed", 405)
}