Package traffic - a Sinatra inspired regexp/pattern mux for Go.
go get github.com/pilu/traffic
- Regexp routing
- Before Filters
- Custom not found handler
- Middlewares
- Examples: Airbrake Middleware, Chrome Logger Middleware
- Templates/Views
- Easy Configuration
- Shows errors and stacktrace in browser
- Serves static files
- Project Generator
development
is the default environment. The above middlewares are loaded only in development
.
If you want to run your application in production
, export TRAFFIC_ENV
with production
as value.
TRAFFIC_ENV=production your-executable-name
Dowload the Traffic
code:
go get github.com/pilu/traffic
Build the command line tool:
go get github.com/pilu/traffic/traffic
Create a new project:
traffic new hello
Run your project:
cd hello
go build && ./hello
You can use Fresh if you want to build and restart your application every time you create/modify/delete a file.
The following code is a simple example, the documentation in still in development.
For more examples check the examples
folder.
package main
import (
"net/http"
"github.com/pilu/traffic"
"fmt"
)
func rootHandler(w traffic.ResponseWriter, r *traffic.Request) {
fmt.Fprint(w, "Hello World\n")
}
func pageHandler(w traffic.ResponseWriter, r *traffic.Request) {
params := r.URL.Query()
fmt.Fprintf(w, "Category ID: %s\n", params.Get("category_id"))
fmt.Fprintf(w, "Page ID: %s\n", params.Get("id"))
}
func main() {
router := traffic.New()
// Routes
router.Get("/", rootHandler)
router.Get("/categories/:category_id/pages/:id", pageHandler)
router.Run()
}
You can also add "before filters" to all your routes or just to some of them:
router := traffic.New()
// Executed before all handlers
router.AddBeforeFilter(checkApiKey).
AddBeforeFilter(addAppNameHeader).
AddBeforeFilter(addTimeHeader)
// Routes
router.Get("/", rootHandler)
router.Get("/categories/:category_id/pages/:id", pageHandler)
// "/private" has one more before filter that checks for a second api key (private_api_key)
router.Get("/private", privatePageHandler).
AddBeforeFilter(checkPrivatePageApiKey)
Complete example:
func rootHandler(w traffic.ResponseWriter, r *traffic.Request) {
fmt.Fprint(w, "Hello World\n")
}
func privatePageHandler(w traffic.ResponseWriter, r *traffic.Request) {
fmt.Fprint(w, "Hello Private Page\n")
}
func pageHandler(w traffic.ResponseWriter, r *traffic.Request) {
params := r.URL.Query()
fmt.Fprintf(w, "Category ID: %s\n", params.Get("category_id"))
fmt.Fprintf(w, "Page ID: %s\n", params.Get("id"))
}
func checkApiKey(w traffic.ResponseWriter, r *traffic.Request) {
params := r.URL.Query()
if params.Get("api_key") != "foo" {
w.WriteHeader(http.StatusUnauthorized)
}
}
func checkPrivatePageApiKey(w traffic.ResponseWriter, r *traffic.Request) {
params := r.URL.Query()
if params.Get("private_api_key") != "bar" {
w.WriteHeader(http.StatusUnauthorized)
}
}
func addAppNameHeader(w traffic.ResponseWriter, r *traffic.Request) {
w.Header().Add("X-APP-NAME", "My App")
}
func addTimeHeader(w traffic.ResponseWriter, r *traffic.Request) {
t := fmt.Sprintf("%s", time.Now())
w.Header().Add("X-APP-TIME", t)
}
func main() {
router := traffic.New()
// Routes
router.Get("/", rootHandler)
router.Get("/categories/:category_id/pages/:id", pageHandler)
// "/private" has one more before filter that checks for a second api key (private_api_key)
router.Get("/private", privatePageHandler).
AddBeforeFilter(checkPrivatePageApiKey)
// Executed before all handlers
router.AddBeforeFilter(checkApiKey).
AddBeforeFilter(addAppNameHeader).
AddBeforeFilter(addTimeHeader)
router.Run()
}