BARF is a small and unobtrusive framework for building JSON-based web APIs on REST or GraphQL-based architectures. It is implemented such that getting started is easy and quick, but it is also flexible enough to allow for more complex use cases.
- No application instance
- No bullsh*t context
- ...and no re-inventing the wheel
It’s just what you need being provided to you in an unobtrusive way.
go get github.com/opensaucerer/barfFor a comprehensive overview on how to use barf, please refer to the example folder and its sub folders.
package main import ( "log" "net/http" "github.com/opensaucerer/barf" ) func main() { // barf tries to be as unobtrusive as possible, so your route handlers still // inherit the standard http.ResponseWriter and *http.Request parameters barf.Get("/", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "Hello World", }) }) // create & start server if err := barf.Beck(); err != nil { // barf exposes a logger instance barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "log" "net/http" "github.com/opensaucerer/barf" ) func main() { // create server if err := barf.Stark(barf.Augment{ Port: "5000", Logging: barf.Allow(), // enable request logging Recovery: barf.Allow(), // enable panic recovery so barf returns a 500 error instead of crashing }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } barf.Get("/", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "Hello World", }) }) // start barf server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "log" "net/http" "github.com/opensaucerer/barf" ) func main() { type Env struct { // Port for the server to listen on Port string `barfenv:"key=PORT;required=true"` // barfenv tag allows barf to load environment variables } env := new(Env) // global environment variable // you can use barf to dynamically load environment variables into a struct if err := barf.Env(env, "example/.env"); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } // create server if err := barf.Stark(barf.Augment{ Port: env.Port, Logging: barf.Allow(), Recovery: barf.Allow(), }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } barf.Get("/", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "Hello World", }) }) // start server - create & start server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "log" "net/http" "github.com/opensaucerer/barf" ) func main() { type Env struct { // Port for the server to listen on Port string `barfenv:"key=PORT;required=true"` } env := new(Env) // global environment variable // load environment variables if err := barf.Env(env, "example/.env"); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } // create server if err := barf.Stark(barf.Augment{ Port: env.Port, Logging: barf.Allow(), Recovery: barf.Allow(), }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } barf.Post("/:username", func(w http.ResponseWriter, r *http.Request) { var data struct { Name string `json:"name"` Age int `json:"age"` } err := barf.Request(r).Body().Format(&data) if err != nil { barf.Response(w).Status(http.StatusBadRequest).JSON(barf.Res{ Status: false, Data: nil, Message: "Invalid request body", }) return } params, _ := barf.Request(r).Params().JSON() query, _ := barf.Request(r).Query().JSON() barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: map[string]interface{}{"params": params, "query": query, "body": data}, Message: "Hello World", }) }) // start server - create & start server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "io" "net/http" "os" "github.com/opensaucerer/barf" ) func main() { type Env struct { // Port for the server to listen on Port string `barfenv:"key=PORT;required=true"` } env := new(Env) // global environment variable // load environment variables if err := barf.Env(env, "example/.env"); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } // create server if err := barf.Stark(barf.Augment{ Port: env.Port, Logging: barf.Allow(), // enable request logging Recovery: barf.Disallow(), }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } // create a subrouter (retroframe) s := barf.RetroFrame("/api").RetroFrame("/v1") s.Get("/about", func(w http.ResponseWriter, r *http.Request) { message := "About" // parsing form-data body, err := barf.Request(r).Form().Body().JSON() if err != nil { message = err.Error() } head := barf.Request(r).Form().File().Get("file") file, _ := head.Open() defer file.Close() // save file f, err := os.OpenFile(head.Filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { message = err.Error() } defer f.Close() io.Copy(f, file) barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: body, Message: message, }) }) // start server - create & start server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "log" "net/http" "github.com/opensaucerer/barf" ) func main() { // create server if err := barf.Stark(barf.Augment{ Port: "5000", Logging: barf.Allow(), // enable request logging Recovery: barf.Allow(), // enable panic recovery so barf returns a 500 error instead of crashing }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } // apply global middleware to all routes - middleware is applied in the order it is added and must be added before the call to barf.Beck() barf.Hippocampus().Hijack(func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Println("before 0") h.ServeHTTP(w, r) log.Println("after 0") }) }) // define routes barf.Get("/", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "Hello World", }) }) // apply another global middleware barf.Hippocampus().Hijack(func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Println("before 1") h.ServeHTTP(w, r) log.Println("after 1") }) }) // start barf server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }package main import ( "net/http" "os" "github.com/opensaucerer/barf" ) func main() { // create server if err := barf.Stark(barf.Augment{ Port: "5000", Logging: barf.Allow(), // enable request logging Recovery: barf.Allow(), // enable panic recovery so barf returns a 500 error instead of crashing }); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } barf.Get("/", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "Hello World", }) }) // create a subrouter (retroframe) s := barf.RetroFrame("/api/v1") s.Get("/about", func(w http.ResponseWriter, r *http.Request) { barf.Response(w).Status(http.StatusOK).JSON(barf.Res{ Status: true, Data: nil, Message: "About", }) }) // start barf server if err := barf.Beck(); err != nil { barf.Logger().Error(err.Error()) os.Exit(1) } }Barf is an open source project and we welcome contributions of all kinds to help improve the project. Please read our contributing guide to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes to Barf.
For a starting point on features Barf currently lacks, see the issues page.
Barf is MIT licensed.
Made with contrib.rocks.
