Using Go for Web (Services|Servers|Sites)

Thomas Kjeldahl Nilsson

@thomanil

thomas.nilsson@shortcut.no

So what would you use Go for?

  • Tools
  • Servers

Things to look at here

  • A very simple use case
  • Some more bits of Go code
  • What's available out of the box (std lib)?
  • Framework/library situation
  • Best practices

Disclaimer:

I'm new at this

http://kjeldahlnilsson.net/shared/beginner.jpg

My hobby project

  • Simple REST backend for an Android app
  • With some web page bits…

The app

http://kjeldahlnilsson.net/shared/screenshot.png

Habit data model

{
"id":"67",
"intervalType":"0", /* 0=daily, 1=weekly, 2=monthly*/
"description":"Walk the dog",
"lastPerformed":"2014-10-10T08:49:53+00:00",
}

REST API should allow app to:

  • List all current habits, and their state
  • Create a new habit
  • Delete an existing habit
  • Update an existing habit with new text or timestamp

Basic web console

Should list the current habit list state for debugging

Framework vs plain standard lib?

  • Big frameworks provide value…
  • … however, you are along for the ride
  • Abstracted away from details = good & bad
  • Bad when learning new stack

Most Go web frameworks build on net/http

Learn that first to understand the basics

(This is what I'm currently doing)

You can pull in parts of frameworks as needed

We'll start with just using the basic Go packages

Let's see how far we get without any external libraries

Let's look at some code

And test as we go along, give me a sec to set up :)

The data model

Routes, responding to urls

How does the persistence work?

Some neat aspects at this point:

  • Single compiled, self-contained binary
  • =few moving parts
  • Deployable to nearly any server architecture

Rendering our habits as a web page

A potential problem with web assets

  • Going from pure api to traditional webapp
  • Need to add served assets, everything no longer inline
  • Compilation of single binary becomes less viable
  • We give up self-contained aspect once we start serving assets/files
  • Alternative: inline text assets, host binary/mutable assets from cloud or database

Our real problem: not very REST-Y!

  • Not great out-of-box support for dynamic url matching
  • Start to feel constraints of "stdlib only"
  • Need to either write our own general routing logic…
  • … or pull in external libraries/frameworks

Ok, let's look into libraries/frameworks

Current major Go web libraries/frameworks

  • Gorilla
  • Negroni
  • Revel
  • Beego

Gorilla

  • Collection of composable packages
  • Built on top of & integrates well with net/http
  • Routing
  • Session handling
  • Cookie handling
  • http form handling
  • higher level http client
  • RSS generation
  • JSON RPC abstraction
  • Websocket RFC 6455 implementation

Negroni

  • Minimal
  • Single focus: http middleware
  • Logging
  • Error recovery
  • Static file serving

Revel

  • "Kitchen sink", focused on productivity
  • Hot code reload
  • Routing
  • Param parsing
  • Validation
  • Sessions
  • Caching
  • Background jobs
  • Test framework
  • Internationalization
  • Hot code reload
  • Maturity: nearing 1.0, FWIW

Beego

  • Another "kitchen sink"
  • Opiniated framework
  • Routing
  • MVC model conventions
  • ORM support
  • Hot reload
  • Test automation
  • Packaging/deployment
  • Sessions, logging, ORM stuff, etc etc
  • Maturity: stable v1.4.1, FWIW

Summary of the frameworks

  • If you need to build a small service and can afford to build bottom up, use Gorilla or Negroni
  • If you need something akin to Rails, Django etc for Go: look into Revel or Beego
  • CAUTION: Beego/Revel likely much less mature than something like Rails, Django or Play!

Let's use Gorilla for purer REST routing

  • How much hassle to set up?
  • Let's look at our code

That's it for code walkthrough

What are current Go best practices?

  • Evolving obviously
  • Generally: go depends on, and encourages, few moving parts
  • Life seems simpler than Java/Ruby/JavaScript & friends
  • Much comes out of the box

Code quality/conventions

  • go fmt + opiniated compiler

Test automation

go test

Builds

standard project structure + "go build" + make/rake/whatever

Dependency management

Faith vs vendoring vs godep?

Deployment

  • Copy executable to server
  • Run executable
  • (+reverse proxy)
  • (+process management tool)

Wrapping up: my current take on Go

Again, pinch of salt here since I'm a newcomer

When would I NOT use it?

Not sure if I'd use it for websites

Rails/Django/Play and friends

Not for delicious abstractions

  • Syntax doesn't send my heart racing
  • Use something else if you badly need DSLs & beautiful code

However, seems great for building tools and services

Most useful bits in my opinion

  • A sane concurrency model
  • Non-verbose static typing
  • Speed of execution
  • Speed of compilation
  • "Grown up" community
  • Well thought out standard libraries, "batteries included"
  • Nice error handling/contract conventions
  • Easy setup & few dependencies
  • Simple, standardized dev env
  • Compile native binaries
  • Simplifed config management
  • Generally encourages self-contained and simple approaches

Junior dev

“How many tools can I add to make my job easy?”

http://kjeldahlnilsson.net/shared/kitchengadgets.png

Senior dev

“How many tools can I subtract to make my job easy?”

http://kjeldahlnilsson.net/shared/chefknife.jpg

Final note about Go & GDG Oslo

We would love to host more Go talks, workshops, etc!

Please let us know in person, over email or on meetup page if you want to see or contribute more Go meetup content!

Bye now!

@thomanil

thomas.nilsson@shortcut.no