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.
funchandleHello(r compass.Request) compass.Response {
returncompass.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 {
returncompass.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")
returncompass.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 textcompass.TextWithCode("nope", 403) // any statuscompass.HTML("<p>hiii</p>") // 200, displayed as HTMLcompass.JsonMarshal(myStruct) // marshals to JSON, 200compass.Redirect("/login", false) // 303 redirectcompass.DownloadFile("report.pdf", path) // triggers a file downloadcompass.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"})
returnrespAnything 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)
returnresp// get it back on the next requestsession, ok:=r.GetSession(server)
// read a valuename, err:=compass.SessionGet[string](session, "name")
pfpLink:=compass.SessionGetOrDefault[string](session, "profilePicture", "/static/default.png")
// write a valuetx:=session.BeginTx()
tx.Set("name", "alice")
tx.Commit()returncompass.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"}}
returncompass.Text("I'm a very secretive text!").WithCORS(policy)server.NotFoundHandler=func(r compass.Request) compass.Response {
returncompass.TextWithCode("not found", 404)
}
server.MethodNotAllowedHandler=func(r compass.Request) compass.Response {
returncompass.TextWithCode("method not allowed", 405)
}