API Reference
A *seatbelt.App
is the core of your application. It contains routing and middleware information, stores templates and internationalization data, and manages sessions and flashes.
It is not an HTTP server. While it does provide a Start()
method for convenience, it is not intended for production use. Instead, you should create an instance of a *http.Server
, and pass the *seatbelt.App
as its Handler
.
package main
import (
"net/http"
"github.com/go-seatbelt/seatbelt"
)
func main() {
app := seatbelt.New()
srv := &http.Server{
Addr: ":3000",
Handler: app,
ReadTimeout: 30 * time.Second,
WriteTimeout: 20 * time.Second,
}
log.Fatalln(srv.ListenAndServe())
}
Use seatbelt.New
to create and configure a new instance of a *seatbelt.App
using the given seabelt.Opts
to configure it. The following options are available:
TemplateDir string
The directory containing your HTML templates. Defaults to"templates"
.LocaleDir string
The directory containing your translation files. Defaults to an empty string, which disables translation support in your application.SigningKey string
The secret key used to sign the session cookie. Defaults to an empty string. Setting an empty string will cause Seatbelt to generate amaster.key
file at the root of your application, which Seatbelt picks up and uses to sign sessions. This generated secret is used for convenience in development only. Do not put this secret under source control, and set this value automatically by setting theSECRET
environment variable in production.SessionName string
The name of the session cookie. Defaults to"_session"
.SessionMaxAge int
The max age that the session cookie is valid. Defaults to 365 days. Pass-1
if you want the session to never expire.Reload bool
Whether to reload the HTML templates and translation data from the filesystem on each request. Defaults tofalse
. This is provided as a convenience in development, but significantly impacts performance. Do not enable this in production.SkipServeFiles bool
When true, this stops Seatbelt from serving static files from thepublic
folder. Defaults tofalse
, meaning that static files are served by default.Funcs func(w http.ResponseWriter, r *http.Request) template.FuncMap
HTML template functions to call from your templates. Defaults tonil
, but please see the list of default functions.
package main
import (
"html/template"
"net/http"
"os"
"github.com/go-seatbelt/seatbelt"
)
func main() {
app := seatbelt.New(seatbelt.Option{
TemplateDir: "templates",
LocaleDir: "locales",
SigningKey: os.Getenv("SECRET"),
SessionName: "_seatbelt",
SessionMaxAge: int(30 * 24 * time.Hour),
Reload: false,
SkipServeFiles: false,
Funcs: func(w http.ResponseWriter, r *http.Request) template.FuncMap {
return template.FuncMap{
"CurrentPath": func(path string) bool {
return r.URL.Path == path
},
}
},
})
}
The method Start()
is a convenience method for starting an HTTP server that runs your application.
The started HTTP server is not suited for production use. Instead, you should create an instance of an *http.Server
, and pass the *seatbelt.App
as its Handler
.
package main
import "github.com/go-seatbelt/seatbelt"
func main() {
app := seatbelt.New()
// Starts an HTTP server on http://localhost:3000
app.Start(":3000")
}
Registers HTTP middleware on the application.
package main
import (
"log"
"github.com/go-seatbelt/seatbelt"
)
// logger is HTTP middleware that logs the path of the current request.
func logger(fn func(c *seatbelt.Context) error) func(*seatbelt.Context) error {
return func(c *seatbelt.Context) error {
log.Println("received request:", c.Request().URL.Path)
return fn(c)
}
}
func main() {
app := seatbelt.New()
app.Use(logger)
}
Registers standard library compatible HTTP middleware on the application.
package main
import (
"log"
"net/http"
"github.com/go-seatbelt/seatbelt"
)
func logger(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("received request: %s\n", r.URL.Path)
h.ServeHTTP(w, r)
})
}
func main() {
app := seatbelt.New()
app.UseStd(logger)
}
Sets the given function as the application-wide error handler. When this handler isn't set, the default behaviour is to log the error, and either reply with the error (for idempotent request) or redirect to the referrer with a flash message containing the error (for all other requests).
package main
import (
"log"
"net/http"
"strings"
"github.com/go-seatbelt/seatbelt"
)
func handleErr(c *seatbelt.Context, err error) {
accept := c.Request().Header.Get("Accept")
if strings.Contains(accept, "application/json") {
c.JSON(500, map[string]string{
"Error": err.Error(),
})
return
}
if strings.Contains(accept, "text/html") {
c.Render("error", map[string]any{
"Error": error
}, seatbelt.RenderOptions{
StatusCode: 500,
})
return
}
return c.String(500, "Error: " + err.Error())
}
func main() {
app := seatbelt.New()
app.SetErrorHandler(handleErr)
}
Registers the given function as an HTTP handler, responding to GET requests at the given path.
Path parameters can be registered on the given URL handler, and accessed in the handler by using c.PathParam
.
package main
import (
"log"
"net/http"
"strings"
"github.com/go-seatbelt/seatbelt"
)
func main() {
app := seatbelt.New()
app.Get("/", func(c *seatbelt.Context) error {
return c.String(200, "Hello, world!")
})
app.Get("/users/{id}", func(c *seatbelt.Context) error {
// Returns the ID provided in the path.
return c.String(200, c.PathParam("id"))
})
app.Start(":3000")
}
TODO
TODO
TODO
TODO
TODO
TODO
TODO
Serves static files from the given pattern under the given path.
Implements the ServeHTTP method in order to satisfy the http.Handler
interface.
A *seatbelt.Context
is an HTTP handler context. It contains the current HTTP request, a response writer, and a number of methods for interacting with the request and response.
package main
import "github.com/go-seatbelt/seatbelt"
// Creates a server that registers a handler on the path "/", and replies with
// "Hello, world!".
func main() {
app := seatbelt.New()
app.Get("/", func (c *seatbelt.Context) error {
return c.String(200, "Hello, world!")
})
app.Start(":3000")
}
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.
TODO.