<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Steven White]]></title><description><![CDATA[Full Stack Web Developer]]></description><link>http://stevenwhite.com/</link><image><url>http://stevenwhite.com/favicon.png</url><title>Steven White</title><link>http://stevenwhite.com/</link></image><generator>Ghost 1.24</generator><lastBuildDate>Mon, 01 Sep 2025 09:20:25 GMT</lastBuildDate><atom:link href="http://stevenwhite.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Go and Lambda]]></title><description><![CDATA[In this tutorial, I'll walk through how easy it is to deploy a  fully functional API using these technologies and others by way of the serverless framework.]]></description><link>http://stevenwhite.com/go-and-lambda/</link><guid isPermaLink="false">5b55041123120f04ed85fd18</guid><category><![CDATA[lambda]]></category><category><![CDATA[golang]]></category><dc:creator><![CDATA[Steven White]]></dc:creator><pubDate>Mon, 23 Jul 2018 04:21:58 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Golang and AWS Lambda are two of the primary tools I use everyday for work, so when AWS <a href="https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/">announced</a> that lambda would natively support Go earlier this year I was ecstatic. In this tutorial, I'll walk through how easy it is to deploy a  fully functional API using these technologies and others by way of the <a href="https://serverless.com/">serverless framework</a>.</p>
<h2 id="disclaimer">Disclaimer</h2>
<p>This tutorial is designed to be deployed to AWS, and while the majority of resources <strong>should</strong> fall under the free tier, please be aware that this could be costing you actual money.</p>
<h2 id="somebackground">Some Background</h2>
<p>So why is official support for Golang in AWS Lambda so great?</p>
<p>Well, firstly, building a Golang application is dead simple, and this makes deployment dead simple. The output of <code>go build</code> is a statically linked binary, and this is literally the only thing you need to deploy an application to lambda.</p>
<p>Second, Golang enjoys one of the lower <a href="https://medium.com/@nathan.malishev/lambda-cold-starts-language-comparison-%EF%B8%8F-a4f4b5f16a62">cold start times</a> of the currently supported languages, and is likely to improve on that mark in the future.</p>
<p>Also, sometimes you just get tired of javascript.</p>
<h2 id="setup">Setup</h2>
<p>Before we get started, we need to prepare our environment.  My machine is setup with the following:</p>
<ul>
<li><a href="https://nodejs.org/en/download/">Node.js</a> v8</li>
<li><a href="https://golang.org/doc/install">Golang</a> 1.10</li>
</ul>
<p>Once that's squared away, we'll need to install the serverless cli.</p>
<pre><code class="language-bash">npm install -g serverless
</code></pre>
<p>You'll also need the <a href="https://aws.amazon.com/cli/">aws cli</a> configured with a set of access credentials to an AWS account you control.</p>
<h2 id="initialproject">Initial Project</h2>
<p>Now that we have our tools installed, we can begin setting up a new project.  Enter <code>serverless</code>.</p>
<pre><code class="language-bash">$ cd somewhere/in/GOPATH
$ serverless create -t aws-go-dep -p go-lambda-test
</code></pre>
<p>Once complete, serverless will scaffold a new project using the <code>aws-go-dep</code> template. This comes with all sorts of goodies:</p>
<ul>
<li><a href="https://github.com/golang/dep">dep</a> has been initialized with the <a href="https://github.com/aws/aws-lambda-go">aws-lambda-go</a> package.</li>
<li>Two very simple lambda functions.</li>
<li>A <code>Makefile</code> for building.</li>
<li>A <code>serverless.yml</code> configuration file.</li>
</ul>
<p>In fact, even in this simple form, we are able to deploy the two functions to lambda and test them out.  I like to add a new build target to the <code>Makefile</code> to facilitate this.  Here's what that looks like:</p>
<pre><code>build:
	dep ensure
	env GOOS=linux go build -ldflags=&quot;-s -w&quot; -o bin/hello hello/main.go
	env GOOS=linux go build -ldflags=&quot;-s -w&quot; -o bin/world world/main.go

deploy: build
	serverless deploy
</code></pre>
<p>From here, we can deploy to AWS and test each function.</p>
<pre><code class="language-bash">$ make deploy
$ serverless invoke -f hello
</code></pre>
<p>If everything goes as expected, you should see the following output:</p>
<pre><code class="language-javascript">{
    &quot;message&quot;: &quot;Go Serverless v1.0! Your function executed successfully!&quot;
}
</code></pre>
<p>Taking a look at the provided <code>hello/main.go</code>, it should pretty intuitive to see what's happening here.</p>
<pre><code class="language-go">package main

import (
	&quot;github.com/aws/aws-lambda-go/lambda&quot;
)

type Response struct {
	Message string `json:&quot;message&quot;`
}

func Handler() (Response, error) {
	return Response{
		Message: &quot;Go Serverless v1.0! Your function executed successfully!&quot;,
	}, nil
}

func main() {
	lambda.Start(Handler)
}
</code></pre>
<p>Our <code>Handler</code> func is being executed on every lambda function invocation, always returning a static response.</p>
<h2 id="addinganapi">Adding an API</h2>
<p>Now that we're starting to get a feel for deploying and executing lambda functions with Golang, let's begin to introduce an API.  First, we'll need to install some dependencies and remove the <code>aws-lambda-go</code> dependency.</p>
<ul>
<li><a href="https://github.com/gin-gonic/gin">gin</a> - http framework</li>
<li><a href="https://github.com/apex/gateway">gateway</a> - lambda wrapper for <code>http.Handler</code> interface</li>
</ul>
<p>To achieve this, we can run:</p>
<pre><code class="language-bash">$ dep ensure -add github.com/gin-gonic/gin github.com/apex/gateway
</code></pre>
<p>You'll likely receive a warning from <code>dep</code> at this point indicating that the installed dependencies are not imported by your project, but we'll address that soon enough. Let's start by creating a new directory for our handler and removing the demo functions.</p>
<pre><code class="language-bash">$ rm -r hello world
$ mkdir cmd
$ touch cmd/handler.go
</code></pre>
<p>Once complete, open up <code>cmd/handler.go</code> and enter the following:</p>
<pre><code class="language-go">package main

import (
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;os&quot;

	&quot;github.com/apex/gateway&quot;
	&quot;github.com/gin-gonic/gin&quot;
)

func foo(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{&quot;success&quot;: true, &quot;message&quot;: &quot;hello lambda API!&quot;})
}

func main() {
	addr := &quot;:3000&quot;
	mode := os.Getenv(&quot;GIN_MODE&quot;)
	g := gin.New()
	g.GET(&quot;/foo&quot;, foo)

	if mode == &quot;release&quot; {
		log.Fatal(gateway.ListenAndServe(addr, g))
	} else {
		log.Fatal(http.ListenAndServe(addr, g))
	}
}
</code></pre>
<p>Basically, what we're doing here boils down to this:</p>
<ul>
<li>Instantiating an instance of <code>*gin.Engine</code>.</li>
<li>Telling that instance to run our <code>foo</code> function when it receives a <code>GET</code> at <code>/foo</code>.</li>
<li>The most interesting part is how we &quot;start the engine&quot;.  If the environment variable <code>GIN_MODE</code> is set to <code>&quot;release&quot;</code>, we wrap our handler with the <code>gateway</code> package, which basically abstracts the API gateway syntax and allows us to focus on the server itself.  Cool, right?</li>
<li>If <code>GIN_MODE</code> does not equal <code>&quot;release&quot;</code>, we start an ordinary http server.</li>
</ul>
<p>Let's go ahead and start a local server to test with first.</p>
<pre><code class="language-bash">$ go run cmd/handler.go
[GIN-debug] [WARNING] Running in &quot;debug&quot; mode. Switch to &quot;release&quot; mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /foo                      --&gt; main.foo (1 handlers)
</code></pre>
<p>And from a separate terminal window, we can test our simple API using curl.</p>
<pre><code class="language-bash">$ curl localhost:3000/foo
{&quot;message&quot;:&quot;hello lambda API!&quot;,&quot;success&quot;:true}
</code></pre>
<p>Great! Now that we're confirmed to be working locally, let's update our <code>Makefile</code> and <code>serverless.yml</code> to know about our new function.</p>
<p>First, the <code>Makefile</code>:</p>
<pre><code>build:
	dep ensure
	env GOOS=linux go build -ldflags=&quot;-s -w&quot; -o bin/handler cmd/handler.go

deploy: build
	serverless deploy
</code></pre>
<p>Then, <code>serverless.yml</code>:</p>
<pre><code class="language-yaml">service: blog-test

provider:
  name: aws
  runtime: go1.x

package:
 exclude:
   - ./**
 include:
   - ./bin/**

functions:
  handler:
    handler: bin/handler
    events:
      - http:
          path: /foo
          method: get
    environment:
      GIN_MODE: release
</code></pre>
<p>A few things to note on these changes. In the <code>Makefile</code>, we remove the old calls to <code>go build</code> and introduce a new one for our handler. In <code>serverless.yml</code>, we're again removing references to our previous functions and adding our handler.</p>
<p>The more interesting part is the addition of <code>events</code>. This block tells <code>serverless</code> what events need to take place in order to invoke our Lambda function. In this case, we're saying that we want our function to be invoked in response to API gateway receiving a <code>GET</code> request to <code>/foo</code>.</p>
<p>Now, we can deploy.</p>
<pre><code class="language-bash">$ make deploy
dep ensure
env GOOS=linux go build -ldflags=&quot;-s -w&quot; -o bin/handler cmd/handler.go
serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (8.07 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.......................................
Serverless: Stack update finished...
Service Information
service: blog-test
stage: dev
region: us-east-1
stack: blog-test-dev
api keys:
  None
endpoints:
  GET - https://ko86rwumf6.execute-api.us-east-1.amazonaws.com/dev/foo # here is your endpoint
functions:
  handler: blog-test-dev-handler
</code></pre>
<p>Be sure to take special care to note the <code>endpoints</code> section of the output. This is the public URL of your API gateway endpoint and should end in <code>/dev/foo</code>.  Let's test that endpoint with curl (yours will be different).</p>
<pre><code class="language-bash">$ curl https://ko86rwumf6.execute-api.us-east-1.amazonaws.com/dev/foo
{&quot;message&quot;:&quot;hello lambda API!&quot;,&quot;success&quot;:true}
</code></pre>
<p>Awesome! We've just deployed our first API written in Golang to Lambda, fronted by API gateway. From here, the world is your oyster.</p>
<h2 id="finished">Finished</h2>
<p>In my next post, we'll look at how to extend our serverless configuration to add a DynamoDB table and integrate that into our API.</p>
</div>]]></content:encoded></item><item><title><![CDATA[Building a REST Service with Golang - Part 3 (Adding a Backend)]]></title><description><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make</p></div>]]></description><link>http://stevenwhite.com/building-a-rest-service-with-golang-3/</link><guid isPermaLink="false">5b53b35e23120f04ed85fd09</guid><category><![CDATA[golang]]></category><category><![CDATA[rest-tutorial]]></category><dc:creator><![CDATA[Steven White]]></dc:creator><pubDate>Sun, 21 Dec 2014 04:42:17 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make for a great tutorial.</p>
<p>At the end, we will have a fully functioning REST service for serving basic CRUD on a user resource. Code for the final product can be found <a href="https://github.com/swhite24/go-rest-tutorial">here</a>.</p>
<p><em>This is the third and final entry in a series of high level tutorials on setting up a REST service using golang, focused on wiring up our previous webserver to a mongo backend.</em></p>
<h3 id="setupmgo">Setup mgo</h3>
<p>At the end of the last tutorial, we had a functioning, albeit useless, webserver offering some CRUD operations on a <code>user</code> resource. In this entry, we will be tying that to a <a href="https://www.mongodb.org/">mongodb</a> backend for persistent data. If you don't have mongo installed on your system, you can find instructions <a href="https://www.mongodb.org/downloads">here</a> or install via <code>brew</code>.</p>
<p>The most popular mongo driver for golang is easily <a href="https://labix.org/mgo">mgo</a>.  We'll be using two packages provided by <code>mgo</code>, <code>mgo</code> itself and <code>bson</code>. We need to grab each package to get going.</p>
<pre><code class="language-bash">$ go get gopkg.in/mgo.v2
$ go get gopkg.in/mgo.v2/bson
</code></pre>
<p>We also need to establish a connection to mongo to provide to our controllers. Add the following function to our <code>server.go</code>.</p>
<pre><code class="language-go">func getSession() *mgo.Session {
	// Connect to our local mongo
	s, err := mgo.Dial(&quot;mongodb://localhost&quot;)

	// Check if connection error, is mongo running?
	if err != nil {
		panic(err)
	}
	return s
}

</code></pre>
<p>Now, our controller is going to need a mongo session to use in the CRUD methods. Let's change how we get a <code>UserController</code> to the following.</p>
<pre><code class="language-go">// Get a UserController instance
uc := controllers.NewUserController(getSession())
</code></pre>
<h3 id="updatetheusercontrollerstruct">Update the UserController struct</h3>
<p>The first thing we need to do to our <code>UserController</code> is to extend the struct to contain a reference to a <code>*mgo.Session</code> so that our controller methods can access mongo. Update the <code>UserController</code> definition to match the following.</p>
<pre><code class="language-go">UserController struct {
	session *mgo.Session
}
</code></pre>
<p>Next, we need to update our <code>NewUserController</code> function to receive a <code>*mgo.Session</code> and instantiate the controller with it.  Update <code>NewUserController</code> to match the following.</p>
<pre><code class="language-go">func NewUserController(s *mgo.Session) *UserController {
	return &amp;UserController{s}
}
</code></pre>
<h3 id="updatetheusermodel">Update the User Model</h3>
<p>Before we start updating the controller methods to use mongo, we need to update our model to integrate with <code>mgo</code>. Similar to how we updated the user model to use a <code>json</code> struct tag for outputting JSON data, we need to add a struct tag to tell <code>mgo</code> how to store the user information.</p>
<p>Update <code>user.go</code> in the <code>models</code> directory to contain the following.</p>
<pre><code class="language-go">package models

import &quot;gopkg.in/mgo.v2/bson&quot;

type (
	// User represents the structure of our resource
	User struct {
		Id     bson.ObjectId `json:&quot;id&quot; bson:&quot;_id&quot;`
		Name   string        `json:&quot;name&quot; bson:&quot;name&quot;`
		Gender string        `json:&quot;gender&quot; bson:&quot;gender&quot;`
		Age    int           `json:&quot;age&quot; bson:&quot;age&quot;`
	}
)

</code></pre>
<p>You'll notice that we are importing only the <code>bson</code> package from <code>mgo</code>. The <code>bson</code> package provides an implementation of the bson specification for go. We use this to change the type of our <code>Id</code> field to a <code>bson.ObjectId</code>.</p>
<p>We also extend each field with a bson struct tag to describe the property name of the mongo document containing the user.</p>
<h3 id="updatethepostcontroller">Update the POST Controller</h3>
<p>Now that our model has been updated and our controller has a reference to an active mongo session, let's start integrating mongo into our service by updating the <code>CreateUser</code> method of our <code>UserController</code>. Update the method to the following.</p>
<pre><code class="language-go">
// CreateUser creates a new user resource
func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Stub an user to be populated from the body
	u := models.User{}

	// Populate the user data
	json.NewDecoder(r.Body).Decode(&amp;u)

	// Add an Id
	u.Id = bson.NewObjectId()

	// Write the user to mongo
	uc.session.DB(&quot;go_rest_tutorial&quot;).C(&quot;users&quot;).Insert(u)

	// Marshal provided interface into JSON structure
	uj, _ := json.Marshal(u)

	// Write content-type, statuscode, payload
	w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	w.WriteHeader(201)
	fmt.Fprintf(w, &quot;%s&quot;, uj)
}
</code></pre>
<p>There are two significant changes here.  First, we ask the <code>bson</code> package for a new ObjectId to store on our user.  Second, we write the user to the <code>users</code> collection in the <code>go_rest_tutorial</code> database.</p>
<p>Let's test adding a user.</p>
<pre><code class="language-bash">$ curl -XPOST -H 'Content-Type: application/json' -d '{&quot;name&quot;: &quot;Bob Smith&quot;, &quot;gender&quot;: &quot;male&quot;, &quot;age&quot;: 50}' http://localhost:3000/user
{&quot;id&quot;:&quot;5497246c380a967ff1000003&quot;,&quot;name&quot;:&quot;Bob Smith&quot;,&quot;gender&quot;:&quot;male&quot;,&quot;age&quot;:50}
</code></pre>
<p>Awesome! Our user was stored in mongo and we have successfully generated an ObjectId.</p>
<h3 id="updatethegetcontroller">Update the GET Controller</h3>
<p>Now that we are able to create new users, it would be nice to be able to fetch them as well.  To do this, let's update the <code>GetUser</code> method of our <code>UserController</code> to the following.</p>
<pre><code class="language-go">
// GetUser retrieves an individual user resource
func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Grab id
	id := p.ByName(&quot;id&quot;)

	// Verify id is ObjectId, otherwise bail
	if !bson.IsObjectIdHex(id) {
		w.WriteHeader(404)
		return
	}

	// Grab id
	oid := bson.ObjectIdHex(id)

	// Stub user
	u := models.User{}

	// Fetch user
	if err := uc.session.DB(&quot;go_rest_tutorial&quot;).C(&quot;users&quot;).FindId(oid).One(&amp;u); err != nil {
		w.WriteHeader(404)
		return
	}

	// Marshal provided interface into JSON structure
	uj, _ := json.Marshal(u)

	// Write content-type, statuscode, payload
	w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	w.WriteHeader(200)
	fmt.Fprintf(w, &quot;%s&quot;, uj)
}
</code></pre>
<p>Again, there a couple of significant changes.  First, we are converting our <code>id</code> path parameter to a <code>bson.ObjectId</code> to be used to find the user. In the event that the id cannot be converted, we bail with a 404 Not Found.  Second, we use our mongo session to find a user matching the provided id from the <code>users</code> collection. We also added an error check when we find the user to deliver a 404 Not Found.</p>
<p>Let's test it out by grabbing the user we created previously.</p>
<pre><code class="language-bash">$ curl http://localhost:3000/user/5497246c380a967ff1000003
{&quot;id&quot;:&quot;5497246c380a967ff1000003&quot;,&quot;name&quot;:&quot;Bob Smith&quot;,&quot;gender&quot;:&quot;male&quot;,&quot;age&quot;:50}
</code></pre>
<p>Sweet! We got the same user that we had posted above. Now if we change the id we should get a 404.</p>
<pre><code class="language-bash">$ curl -i http://localhost:3000/user/5497246c380a967ff1000004
HTTP/1.1 404 Not Found
Date: Sun, 21 Dec 2014 19:58:34 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
</code></pre>
<h3 id="updatethedeletecontroller">Update the DELETE Controller</h3>
<p>So we are able to create new users and retrieve them, now let's add the ability to remove them. To accomplish this, let's update the <code>RemoveUser</code> method of our controller to the following.</p>
<pre><code class="language-go">
// RemoveUser removes an existing user resource
func (uc UserController) RemoveUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Grab id
	id := p.ByName(&quot;id&quot;)

	// Verify id is ObjectId, otherwise bail
	if !bson.IsObjectIdHex(id) {
		w.WriteHeader(404)
		return
	}

	// Grab id
	oid := bson.ObjectIdHex(id)

	// Remove user
	if err := uc.session.DB(&quot;go_rest_tutorial&quot;).C(&quot;users&quot;).RemoveId(oid); err != nil {
		w.WriteHeader(404)
		return
	}

	// Write status
	w.WriteHeader(200)
}
</code></pre>
<p>As you can see, we are again getting an ObjectId out of the <code>id</code> path parameter, and bailing with a 404 if the id cannot by converted to an ObjectId.  We then remove the document matching this id and deliver a 200.</p>
<p>We can test this by first deleting the user we created, then trying to fetch the user.</p>
<pre><code class="language-bash">$ curl -XDELETE http://localhost:3000/user/5497246c380a967ff1000003
$ curl -i http://localhost:3000/user/5497246c380a967ff1000003
HTTP/1.1 404 Not Found
Date: Sun, 21 Dec 2014 20:04:28 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
</code></pre>
<p>Great! We removed the user and confirmed that the user no longer exists.</p>
<h3 id="fin">Fin</h3>
<p>This is end of the tutorial on adding a backend to our REST service, and also the end of the tutorial series in general. While there most certainly are many improvements to be made, such as adding some security and <em>much</em> better error handling, hopefully this high-level overview has been beneficial.</p>
<h3 id="resources">Resources</h3>
<ul>
<li><a href="https://www.mongodb.org/">mongodb</a></li>
<li><a href="https://labix.org/mgo">mgo</a></li>
</ul>
</div>]]></content:encoded></item><item><title><![CDATA[Building a REST Service with Golang - Part 2 (Basic Webserver)]]></title><description><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make</p></div>]]></description><link>http://stevenwhite.com/building-a-rest-service-with-golang-2/</link><guid isPermaLink="false">5b53b35e23120f04ed85fd08</guid><category><![CDATA[golang]]></category><category><![CDATA[rest-tutorial]]></category><dc:creator><![CDATA[Steven White]]></dc:creator><pubDate>Sat, 20 Dec 2014 21:52:21 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make for a great tutorial.</p>
<p>At the end, we will have a fully functioning REST service for serving basic CRUD on a user resource. Code for the final product can be found <a href="https://github.com/swhite24/go-rest-tutorial">here</a>.</p>
<p><em>This is the second in a series of high level tutorials on setting up a REST service using golang, focused on using public packages and defining a basic webserver.</em></p>
<h3 id="packages">Packages</h3>
<p>Go allows for external packages to be accessed in your source via the <code>import</code> statement. These packages must be accessible somewhere in your <code>GOPATH</code> or <code>GOROOT</code> environment, depending on whether the packages come from a third party or the Go standard library, respectively.  In the previous tutorial, you may have noticed that we imported the <code>fmt</code> package when we tested our setup.  The <code>fmt</code> package is part of the standard library.  You can find more standard library packages <a href="http://golang.org/pkg/">here</a>.</p>
<p>Third party packages can be fetched via the <code>go get</code> command.  There are a few special rules for fetching a remote package, <a href="https://golang.org/doc/code.html#remote">described here</a>, but for now we just need to understand the rules for packages publicly available on github. Put simply, any go package on github can fetched via the following.</p>
<pre><code class="language-bash">$ go get github.com/USER/PROJECT
</code></pre>
<p>You'll notice there is no version information in the above command, which is another caveat of go.  There are several solutions for this, such as using a makefile to set a temporary GOPATH within the application and checking dependencies into your source control.  I've also grown fond of <a href="https://github.com/tools/godep">GoDep</a>.</p>
<h3 id="router">Router</h3>
<p>Since we're trying to build out a webserver, let's find a router package. When searching for a go package to use, <a href="http://godoc.org/">GoDoc</a> is always a good place to start. There are many excellect candidates, but let's use the <a href="https://github.com/julienschmidt/httprouter">httprouter package</a>.  We first need to fetch the package with <code>go get</code>.</p>
<pre><code class="language-bash">$ go get github.com/julienschmidt/httprouter
</code></pre>
<p>To get started, we first need to create a directory to host our application. If you followed along with the last tutorial, the following will get us started.  Otherwise, setup a new directory somewhere in your <code>GOPATH</code>.</p>
<pre><code class="language-bash">$ mkdir -p ~/src/go/src/github.com/swhite24/go-rest-tutorial
</code></pre>
<p>Now for some code. Let's add a <code>server.go</code> to bootstrap our app.</p>
<pre><code class="language-go">package main

import (
	// Standard library packages
	&quot;fmt&quot;
	&quot;net/http&quot;

	// Third party packages
	&quot;github.com/julienschmidt/httprouter&quot;
)

func main() {
	// Instantiate a new router
	r := httprouter.New()

	// Add a handler on /test
	r.GET(&quot;/test&quot;, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		// Simply write some test data for now
		fmt.Fprint(w, &quot;Welcome!\n&quot;)
	})

	// Fire up the server
	http.ListenAndServe(&quot;localhost:3000&quot;, r)
}

</code></pre>
<p>Let's break down the <code>main</code> function.</p>
<pre><code class="language-go">r := httprouter.New()
</code></pre>
<p>Here we are instantiating a new httprouter instance. Documentation for public packages can be found at <a href="http://godoc.org/">GoDoc</a>, with the documentation for this package <a href="http://godoc.org/github.com/julienschmidt/httprouter">available here</a>.</p>
<pre><code class="language-go">r.GET(&quot;/test&quot;, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	// Simply write some test data for now
	fmt.Fprint(w, &quot;Welcome!\n&quot;)
})
</code></pre>
<p>Here we are adding a new handler to respond to the <code>&quot;/test&quot;</code> route. Notice that the handler itself has a different signature than the standard <code>http.HandlerFunc</code>.</p>
<p>Also, we are able to respond to the request with <code>fmt.Fprint</code>. Strangely, if you look at the signature of <code>fmt.Fprint</code>, it shows the following.</p>
<pre><code class="language-go">func Fprint(w io.Writer, a ...interface{}) (n int, err error)
</code></pre>
<p>So how are we able to pass our instance of <code>http.ResponseWriter</code> to it as an <code>io.Writer</code>?  Because <code>io.Writer</code> is an <strong>interface</strong>.  Interfaces are implemented implicitly in go. In fact, <code>http.ResponseWriter</code> itself is an interface, which also satisfies the <code>io.Writer</code> interface.</p>
<p>And for the last interesting piece.</p>
<pre><code class="language-go">http.ListenAndServe(&quot;localhost:3000&quot;, r)
</code></pre>
<p>Here, as you can guess, we are firing up a webserver to listen on <code>localhost:3000</code>, using our router to handle requests.  This is another instance where we can see the power of interfaces in go. <code>http.ListenAndServe</code> accepts an interface type <code>http.Handler</code>, which the author of <code>httprouter</code> provides as a convencience.</p>
<p>Let's go ahead and test our example server.  First, fire it up.</p>
<pre><code class="language-bash">$ go run server.go

</code></pre>
<p>Then, in another terminal, hit our router with a curl statement.</p>
<pre><code class="language-bash">$ curl http://localhost:3000/test
Welcome!
</code></pre>
<p>Sweet!</p>
<h3 id="models">Models</h3>
<p>When building webapps in go, I tend to modularize the components as much as possible, both for testing purposes and readability. <strong>Models</strong> are one example  of a piece of functionality I usually break into a separate package.</p>
<p>First, we need to create a directory within our application for the new package. Since I want it to be referred to as <code>models</code>, I'll name the directory the same. This is not required, but I find it to be a good convention.</p>
<pre><code class="language-bash">$ mkdir models
</code></pre>
<p>Now let's add a file in the <code>models</code> directory to represent the structure of our user resource. I'll call it something crazy like <code>user.go</code>.</p>
<pre><code class="language-go">package models

type (
	// User represents the structure of our resource
	User struct {
		Name   string
		Gender string
		Age    int
        Id     string
	}
)
</code></pre>
<p>Simple right? The only thing in this file is the definition of a user.  A more complex resource may contain additional methods our references to other types.</p>
<p>Now, let's stub our router with a new handler function to handle retrieving a user. Update <code>server.go</code> to the following.</p>
<pre><code class="language-go">package main

import (
	// Standard library packages
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;

	// Third party packages
	&quot;github.com/julienschmidt/httprouter&quot;
	&quot;github.com/swhite24/go-rest-tutorial/models&quot;
)

func main() {
	// Instantiate a new router
	r := httprouter.New()

	// Get a user resource
	r.GET(&quot;/user/:id&quot;, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
		// Stub an example user
		u := models.User{
			Name:   &quot;Bob Smith&quot;,
			Gender: &quot;male&quot;,
			Age:    50,
			Id:     p.ByName(&quot;id&quot;),
		}

		// Marshal provided interface into JSON structure
		uj, _ := json.Marshal(u)

		// Write content-type, statuscode, payload
		w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
		w.WriteHeader(200)
		fmt.Fprintf(w, &quot;%s&quot;, uj)
	})

	// Fire up the server
	http.ListenAndServe(&quot;localhost:3000&quot;, r)
}

</code></pre>
<p>You'll notice two major changes.  First, we added an import statement for our newly created <code>models</code> package. Second, we added a new handler to respond to &quot;/user/:id&quot; for retrieving a user. For those unfamiliar with this pattern, <code>:id</code> represents a parameter we can retrieve from the path, which we do to populate the <code>Id</code> field of our user. We also call <code>json.Marshal</code> on our user, which will decode our user into a JSON representation, and deliver that to the client.</p>
<p>Restart the server and test it out with a curl statement.</p>
<pre><code class="language-bash">$ curl http://localhost:3000/user/1
{&quot;Name&quot;:&quot;Bob Smith&quot;,&quot;Gender&quot;:&quot;male&quot;,&quot;Age&quot;:50,&quot;Id&quot;:&quot;1&quot;}
</code></pre>
<p>Sweet! We have our example user. But do we really want to deliver the user with capitalized field names? Probably not. We could try to use lower case field names on the user struct, but then the fields will no longer be exported and available in our main package.</p>
<p>The documentation for the <a href="https://golang.org/pkg/encoding/json/">json package</a> tells us that we can &quot;alias&quot; field names to be whatever we want using <strong>struct tags</strong>.</p>
<p>Let's update our <code>user.go</code> file to use lower case names when delivering json.</p>
<pre><code class="language-go">package models

type (
	// User represents the structure of our resource
	User struct {
		Name   string `json:&quot;name&quot;`
		Gender string `json:&quot;gender&quot;`
		Age    int    `json:&quot;age&quot;`
		Id     string `json:&quot;id&quot;`
	}
)

</code></pre>
<p>Now, let's restart the server and test the route again.</p>
<pre><code class="language-bash">$ curl http://localhost:3000/user/1
{&quot;name&quot;:&quot;Bob Smith&quot;,&quot;gender&quot;:&quot;male&quot;,&quot;age&quot;:50,&quot;id&quot;:&quot;1&quot;}
</code></pre>
<p>Much better.</p>
<p>Finally, if we stub out the remaining routes for our user resource we will have something like this in <code>server.go</code>.</p>
<pre><code class="language-go">
r.POST(&quot;/user&quot;, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	// Stub an user to be populated from the body
	u := models.User{}

	// Populate the user data
	json.NewDecoder(r.Body).Decode(&amp;u)

	// Add an Id
	u.Id = &quot;foo&quot;

	// Marshal provided interface into JSON structure
	uj, _ := json.Marshal(u)

	// Write content-type, statuscode, payload
	w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	w.WriteHeader(201)
	fmt.Fprintf(w, &quot;%s&quot;, uj)
})

r.DELETE(&quot;/user/:id&quot;, func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// TODO: only write status for now
	w.WriteHeader(200)
})
</code></pre>
<h3 id="controllers">Controllers</h3>
<p>One thing you may begin to notice is that our <code>server.go</code> is getting rather bloated with handlers. This is another piece of functionality I typically refactor into a package. Let's do that into a package called <code>controllers</code>.</p>
<p>First, make the directory.</p>
<pre><code class="language-bash">$ mkdir controllers
</code></pre>
<p>Then, add a <code>user.go</code> into the directory.</p>
<pre><code class="language-go">package controllers

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;

	&quot;github.com/julienschmidt/httprouter&quot;
	&quot;github.com/swhite24/go-rest-tutorial/models&quot;
)

type (
	// UserController represents the controller for operating on the User resource
	UserController struct{}
)

func NewUserController() *UserController {
	return &amp;UserController{}
}

// GetUser retrieves an individual user resource
func (uc UserController) GetUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Stub an example user
	u := models.User{
		Name:   &quot;Bob Smith&quot;,
		Gender: &quot;male&quot;,
		Age:    50,
		Id:     p.ByName(&quot;id&quot;),
	}

	// Marshal provided interface into JSON structure
	uj, _ := json.Marshal(u)

	// Write content-type, statuscode, payload
	w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	w.WriteHeader(200)
	fmt.Fprintf(w, &quot;%s&quot;, uj)
}

// CreateUser creates a new user resource
func (uc UserController) CreateUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Stub an user to be populated from the body
	u := models.User{}

	// Populate the user data
	json.NewDecoder(r.Body).Decode(&amp;u)

	// Add an Id
	u.Id = &quot;foo&quot;

	// Marshal provided interface into JSON structure
	uj, _ := json.Marshal(u)

	// Write content-type, statuscode, payload
	w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
	w.WriteHeader(201)
	fmt.Fprintf(w, &quot;%s&quot;, uj)
}

// RemoveUser removes an existing user resource
func (uc UserController) RemoveUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// TODO: only write status for now
	w.WriteHeader(200)
}

</code></pre>
<p>You'll notice that we simply made an exact copy of the handlers previously found in <code>server.go</code> and moved them to individual methods of our user controller type.</p>
<p>An updated <code>server.go</code> to use our new controller looks like the following.</p>
<pre><code class="language-go">package main

import (
	// Standard library packages
	&quot;net/http&quot;

	// Third party packages
	&quot;github.com/julienschmidt/httprouter&quot;
	&quot;github.com/swhite24/go-rest-tutorial/controllers&quot;
)

func main() {
	// Instantiate a new router
	r := httprouter.New()

	// Get a UserController instance
	uc := controllers.NewUserController()

	// Get a user resource
	r.GET(&quot;/user/:id&quot;, uc.GetUser)

	r.POST(&quot;/user&quot;, uc.CreateUser)

	r.DELETE(&quot;/user/:id&quot;, uc.RemoveUser)

	// Fire up the server
	http.ListenAndServe(&quot;localhost:3000&quot;, r)
}


</code></pre>
<p>Much cleaner! Let's run another curl to verify everything is still working.</p>
<pre><code class="language-bash">$ curl http://localhost:3000/user/1
{&quot;name&quot;:&quot;Bob Smith&quot;,&quot;gender&quot;:&quot;male&quot;,&quot;age&quot;:50,&quot;id&quot;:&quot;1&quot;}
</code></pre>
<h3 id="fin">Fin</h3>
<p>That's the end of the tutorial on setting up a basic webserver with golang. We've created an <code>httprouter</code> instance, a model for our <code>user</code> resource, a controller for our <code>user</code> resource, and finally wired them all together.</p>
<p>Next time, we'll add a backend to get a true webservice feel.  <a href="http://stevenwhite.com/building-a-rest-service-with-golang-3/">Check it out</a>.</p>
<h3 id="resources">Resources</h3>
<ul>
<li><a href="http://godoc.org">GoDoc</a></li>
<li><a href="http://godoc.org/github.com/julienschmidt/httprouter">httprouter</a></li>
<li><a href="https://github.com/tools/godep">GoDep</a></li>
<li><a href="https://golang.org/pkg/net/http/">http Docs</a></li>
</ul>
</div>]]></content:encoded></item><item><title><![CDATA[Building a REST Service with Golang - Part 1 (Setup)]]></title><description><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make</p></div>]]></description><link>http://stevenwhite.com/building-a-rest-service-with-golang-1/</link><guid isPermaLink="false">5b53b35e23120f04ed85fd07</guid><category><![CDATA[golang]]></category><category><![CDATA[rest-tutorial]]></category><dc:creator><![CDATA[Steven White]]></dc:creator><pubDate>Sat, 20 Dec 2014 01:50:08 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h3 id="intro">Intro</h3>
<p><a href="http://golang.org">Golang</a> is pretty hot right now.  Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with <a href="http://nodejs.org">node</a> in go, partly for fun, partly because go is <strong>fast</strong>. This led me to believe that setting up a basic REST service would make for a great tutorial.</p>
<p>At the end, we will have a fully functioning REST service for serving basic CRUD on a user resource. Code for the final product can be found <a href="https://github.com/swhite24/go-rest-tutorial">here</a>.</p>
<p><em>This is the first in a series of high level tutorials on setting up a REST service using golang, focused on getting a go dev environment setup.</em></p>
<h3 id="setup">Setup</h3>
<p>The first step to start rocking some go is to get it installed.  Being a mac user, I initially installed go globally with brew, but then reverted to using <a href="https://github.com/moovweb/gvm">gvm</a>, as I love the flexibility I get with its node counterpart, <a href="https://github.com/creationix/nvm">nvm</a>.</p>
<p>Here we go:</p>
<pre><code class="language-bash"># Install gvm
$ bash &lt; &lt;(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

# Install the latest go version (as of this writing)
$ gvm install go1.4

# Set it as active, and the default choice
$ gvm use go1.4 --default
</code></pre>
<p>Done.</p>
<p>So now we have a local version of go installed, our <code>GOPATH</code> and <code>PATH</code> are setup, and we have access to the <code>go</code> executable. Now what?  One of the neat things about gvm is the notion of <code>pkgsets</code>, basically allowing you to define separate &quot;workspaces&quot; and group a set of  go projects using the same go version.</p>
<p>Let's create a pkgset called &quot;work&quot;.</p>
<pre><code class="language-bash"># Create the pkgset
$ gvm pkgset create work

# Set it as active, and the default choice
$ gvm pkgset use work --default
</code></pre>
<p>Sweet. Now, if we inspect our <code>GOPATH</code> and <code>PATH</code>, we can see that they have been updated to reflect our pkgset location. But what if we don't want to work in <code>~/.gvm/pkgsets/go1.4/work/</code>?  Let's setup a directory for our code, say <code>~/src/go</code>.</p>
<pre><code class="language-bash"># Or something else
$ mkdir -p ~/src/go/{bin,pkg,src}
</code></pre>
<p>Now that we have the proper folder structure for go, we'll need to update our environment.  We could manually set <code>GOPATH</code> and <code>PATH</code> to be prefixed with our new <code>src</code> directory, but there's a better way.  We'll use the <code>gvm pkgenv</code> command with our fresh <code>work</code> pkgset so that our new workspace will always be found in <code>GOPATH</code>.</p>
<p>Enter the following to pull open the environment variables for the <code>work</code> pkgset.  We'll be changing the <code>GOPATH</code> and <code>PATH</code> variables to look at <code>~/src/go</code>. Obviously, adjust your entries to reflect the directory structure on your machine.</p>
<pre><code class="language-bash"># Pull open the environment in our favoriate editor
$ gvm pkgenv work
</code></pre>
<pre><code class="language-bash">export GVM_ROOT; GVM_ROOT=&quot;/Users/swhite/.gvm&quot;
export gvm_go_name; gvm_go_name=&quot;go1.4&quot;
export gvm_pkgset_name; gvm_pkgset_name=&quot;global&quot;
export GOROOT; GOROOT=&quot;$GVM_ROOT/gos/go1.4&quot;
export GOPATH; GOPATH=&quot;$GVM_ROOT/pkgsets/go1.4/global&quot;
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX=&quot;${GVM_ROOT}/pkgsets/go1.4/global/overlay&quot;
export PATH; PATH=&quot;${GVM_ROOT}/pkgsets/go1.4/global/bin:${GVM_ROOT}/gos/go1.4/bin:${GVM_OVERLAY_PREFIX}/bin:${GVM_ROOT}/bin:${PATH}&quot;
export LD_LIBRARY_PATH; LD_LIBRARY_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}&quot;
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}&quot;
export PKG_CONFIG_PATH; PKG_CONFIG_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}&quot;
export gvm_pkgset_name=&quot;blog&quot;

# Prefix with our go path we created
export GOPATH; GOPATH=&quot;$HOME/src/go:/Users/swhite/.gvm/pkgsets/go1.4/blog:$GOPATH&quot;

# Prefix with the bin directory in our gopath
export PATH; PATH=&quot;$HOME/src/go/bin:/Users/swhite/.gvm/pkgsets/go1.4/blog/bin:$PATH&quot;

# Package Set-Specific Overrides
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX=&quot;${GVM_ROOT}/pkgsets/go1.4/blog/overlay&quot;
export PATH; PATH=&quot;/Users/swhite/.gvm/pkgsets/go1.4/blog/bin:${GVM_OVERLAY_PREFIX}/bin:${PATH}&quot;
export LD_LIBRARY_PATH; LD_LIBRARY_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}&quot;
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}&quot;
export PKG_CONFIG_PATH; PKG_CONFIG_PATH=&quot;${GVM_OVERLAY_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}&quot;
</code></pre>
<p>So now we can re-use our pkgset and our environment will be nice and reasonable.</p>
<pre><code class="language-bash">$ gvm pkgset use work
</code></pre>
<h3 id="testitout">Test it out</h3>
<p>Let's throw together a package to verify our environment it setup properly.  First create a folder in the <code>~/src/go/src</code> directory to house our code. Let's simply call it <code>test</code>.</p>
<pre><code class="language-bash">$ mkdir ~/src/go/src/test
$ cd ~/src/go/src/test
</code></pre>
<p>As far as editors are concerned, I ordinarily go for <a href="http://www.sublimetext.com/">Sublime Text</a>, but have recently been hacking with <a href="https://atom.io/">Atom</a>.  When writing go code, I highly recommend the <a href="https://atom.io/packages/go-plus">go-plus</a> package.</p>
<p>Now, let's run the canonical intro program. Add the following to <code>test.go</code>.</p>
<pre><code class="language-go">package main

import &quot;fmt&quot;

func main() {
	fmt.Println(&quot;Hello, Gopher!&quot;)
}
</code></pre>
<p>We can run the program with the following.</p>
<pre><code class="language-bash">$ go run test.go
Hello, Gopher!
</code></pre>
<h3 id="fin">Fin</h3>
<p>That's the end of the introductory tutorial on building a REST service with golang. We've setup a proper go dev environment and have built a simple go program. Next we'll learn about using third party packages and setting up a basic webserver.  <a href="http://stevenwhite.com/building-a-rest-service-with-golang-2/">Check it out</a>.</p>
<h3 id="resources">Resources</h3>
<ul>
<li><a href="https://golang.org/doc/install">Getting Started with Go</a></li>
<li><a href="https://golang.org/doc/code.html">How to Write Go Code</a></li>
<li><a href="https://tour.golang.org">A Tour of Go</a></li>
</ul>
</div>]]></content:encoded></item></channel></rss>