Fireball is a package for Go web applications. The primary goal of this package is to make routing, response writing, and error handling as easy as possible for developers, so they can focus more on their application logic, and less on repeated patterns.
To install this package, run:
go get github.com/zpatrick/fireball
The following snipped shows a simple "Hello, World" application using Fireball:
package main
import (
"github.com/zpatrick/fireball"
"net/http"
)
func index(c *fireball.Context) (fireball.Response, error) {
return fireball.NewResponse(200, []byte("Hello, World!"), nil), nil
}
func main() {
indexRoute := &fireball.Route{
Path: "/",
Handlers: fireball.Handlers{
"GET": index,
},
}
routes := []*fireball.Route{indexRoute}
app := fireball.NewApp(routes)
http.ListenAndServe(":8000", app)
}
This will run a new webserver at localhost:8000
Handlers perform the business logic associated with requests. Handlers take a Context object and returns either a Response or an error.
The HTTP Response is a simple object that implements the Response interface. When the Write call is executed, the specified Body, Status, and Headers will be written to the http.ResponseWriter.
Examples:
func Index(c *fireball.Context) (fireball.Response, error) {
return fireball.NewResponse(200, []byte("Hello, World"), nil), nil
}
func Index(c *fireball.Context) (fireball.Response, error) {
html := []byte("<h1>Hello, World</h1>")
return fireball.NewResponse(200, html, fireball.HTMLHeaders), nil
}
If a Handler returns a non-nil error, the Fireball Application will call its ErrorHandler function. By default (if your Application object uses the DefaultErrorHandler), the Application will check if the error implements the Response interface. If so, the the error's Write function will be called. Otherwise, a 500 with the content of err.Error() will be written.
The HTTPError is a simple object that implements both the Error and Response interfaces. When the Write is executed, the specified status, error, and headers will be written to the http.ResponseWriter.
Examples:
func Index(c *fireball.Context) (fireball.Response, error) {
return nil, fmt.Errorf("an error occurred")
}
func Index(c *fireball.Context) (fireball.Response, error) {
if err := do(); err != nil {
return nil, fireball.NewError(500, err, nil)
}
...
}
By default, Fireball uses the BasicRouter object to match requests to Route objects. The Route's Path field determines which URL patterns should be dispached to your Route. The Route's Handlers field maps different HTTP methods to different Handlers.
You can use :variable
notation in the Path to match any string that doesn't contain a "/"
character.
The variables defined in the Route's Path field can be accessed using the Context object.
Example:
route := &Fireball.Route{
Path: "/users/:userID/orders/:orderID",
Methods: fireball.Handlers{
"GET": printUserOrder,
},
}
func printUserOrder(c *fireball.Context) (fireball.Response, error) {
userID := c.PathVariables["userID"]
orderID := c.PathVariables["orderID"]
message := fmt.Sprintf("User %s ordered item %s", userID, orderID)
return fireball.NewResponse(200, []byte(message), nil)
}
The built-in FileServer can be used to serve static content.
The follow snippet would serve files from the static
directory:
app := fireball.NewApp(...)
http.Handle("/", app)
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static", fs))
http.ListenAndServe(":8000", nil)
If the application workspace contained:
app/
main.go
static/
hello_world.txt
A request to /static/hello_world.txt
would serve the desired file.
By default, Fireball uses the GlobParser to render HTML templates.
This object recursively searches a given directory for template files matching the given glob pattern.
The default root directory is "views"
, and the default glob pattern is "*.html"
The name of the templates are path/from/root/directory
+ filename
.
For example, if the filesystem contained:
views/
index.html
partials/
login.html
The templates names generated would be "index.html"
, and "partials/login.html"
.
The Context contains a helper function, HTML, which renders templates as HTML.
Example:
func Index(c *fireball.Context) (fireball.Response, error) {
data := "Hello, World!"
return c.HTML(200, "index.html", data)
}
Decorators can be used to wrap additional logic around Handlers. Fireball has some built-in decorators:
- BasicAuthDecorator adds basic authentication using a specified username and password
- LogDecorator logs incoming requests
In addition to Decorators, the Before and After functions on the Application object can be used to perform logic when the request is received and after the response has been sent.
This work is published under the MIT license.
Please see the LICENSE
file for details.