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 <code>json:"name"
Age intjson:"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 <code>json:"id"
Name stringjson:"name"
Age intjson:"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.