When you want to create a rest service or web application in Go, you have to do a lot of work around project setup, application architecture, directory structures, and more. What if there was a web development platform that already has everything from front-end (JavaScript, CSS) to back-end (database, routing), designed to make the life of a Go web developer easier. Well, there is, it is called Buffalo. Lets take a look!
Buffalo
Buffalo is a web application development environment for Go, inspired by Ruby on Rails, the Play Framework, Django and other rapid application web frameworks. Buffalo makes use of the Gorilla toolkit, a web toolkit for Go.
Install
Buffalo can be installed by typing:
# from source with sqlite3 support
go get -u -v -tags sqlite github.com/gobuffalo/buffalo/buffalo
# from source *without* sqlite3 support
go get -u -v github.com/gobuffalo/buffalo-plugins
# using homebrew
$ brew install gobuffalo/tap/buffalo
After installation you should have the buffalo
cli installed:
$ buffalo version
INFO[0000] Buffalo version is: v0.13.7
A REST API
Buffalo can also create simple REST APIs. Buffalo v0.13.7 does not support modules, so you have to create a directory in $GOPATH eg. $GOPATH/src/github.com/binxio/blog-go-buffalo
and type the following
$ buffalo new go_blog_buffalo --api --skip-pop
$ cd go_blog_buffalo
$ buffalo dev
buffalo: 2018/11/27 19:16:41 === Rebuild on: :start: ===
buffalo: 2018/11/27 19:16:41 === Running: go build -v -i -tags development -o tmp/go-buffalo-build (PID: 17379) ===
buffalo: 2018/11/27 19:16:42 === Building Completed (PID: 17379) (Time: 1.322165735s) ===
buffalo: 2018/11/27 19:16:42 === Running: tmp/go-buffalo-build (PID: 17397) ===
INFO[2018-11-27T19:16:45+01:00] Starting application at 127.0.0.1:3000
INFO[2018-11-27T19:16:45+01:00] Starting Simple Background Worker
The service is available at port ‘3000’:
$ http :3000
HTTP/1.1 200 OK
Content-Length: 34
Content-Type: application/json
Date: Tue, 27 Nov 2018 18:17:36 GMT
Vary: Origin
{
"message": "Welcome to Buffalo!"
}
Generator
Buffalo comes with a generator that can generate Actions. Lets start a second terminal, navigate to $GOPATH/src/github.com/binxio/blog-go-buffalo
and type:
$ buffalo g a cats List --skip-template
The generator has created a cats.go
file with the CatsList
action.
Change the following lines in app.go
:
// change this line
app.GET("/cats/List", CatsList)
// to this line
app.GET("/cats", CatsList)
Notice that Buffalo automatically compiles and reloads the server to reflect the changes to the application.
Lets implement the CatsList
handler in cats.go
:
package actions
import "github.com/gobuffalo/buffalo"
type Cat struct {
Name string `json:"name"`
Age int `json:"age"`
}
var cats = []Cat {
Cat { Name: "Elsa", Age: 16 },
Cat { Name: "Tijger", Age: 12 },
}
// CatsList default implementation.
func CatsList(c buffalo.Context) error {
return c.Render(200, r.JSON(cats))
}
Call the endpoint:
$ http :3000/cats
HTTP/1.1 200 OK
Content-Length: 54
Content-Type: application/json
Date: Tue, 27 Nov 2018 18:42:38 GMT
Vary: Origin
[
{
"age": 16,
"name": "Elsa"
},
{
"age": 12,
"name": "Tijger"
}
]
Lets add a new route with the command:
$ buffalo g a cats GetById --skip-template
Change the following lines in app.go
:
// change this line
app.GET("/cats/GetById", CatsGetByID)
// to this line
app.GET("/cats/{id:[0-9]+}", CatsGetByID)
Add the following implementation to cats.go
:
package actions
import (
"github.com/gobuffalo/buffalo"
"github.com/gorilla/mux"
"net/http"
"strconv"
)
type Cat struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
var cats = []Cat{
Cat{ID: 1, Name: "Elsa", Age: 16},
Cat{ID: 2, Name: "Tijger", Age: 12},
}
func CatsList(c buffalo.Context) error {
return c.Render(http.StatusOK, r.JSON(cats))
}
func CatsGetByID(c buffalo.Context) error {
params := mux.Vars(c.Request())
id, _ := strconv.Atoi(params["id"])
for _, cat := range cats {
if cat.ID == id {
return c.Render(http.StatusOK, r.JSON(cat))
}
}
return c.Render(http.StatusNotFound, nil)
}
And call the endpoint:
$ http :3000/cats/1
HTTP/1.1 200 OK
Content-Length: 32
Content-Type: application/json
Date: Tue, 27 Nov 2018 18:51:09 GMT
Vary: Origin
{
"age": 16,
"id": 1,
"name": "Elsa"
}
Conclusion
Buffalo makes it really easy to create rest services. Buffalo creates a project skeleton, generates actions and templates, runs the server and provides hot reload on code change. We have created two actions, one for cats and one to get a cat by id. Buffalo makes use of the Gorilla toolkit what makes it easy for us to extend the REST service with functionality. I will definitely use Buffalo for a next project.