Since I could not find a complete example of a GO REST Call that returned JSON and used Digest Auth (for Digital Rebar API), I wanted to feed the SEO monster for the next person.
My purpose is to illustrate the pattern, not deliver reference code. Once I got all the pieces in the right place, the code was wonderfully logical. The basic workflow is:
- define a structure with JSON mapping markup
- define an alternate HTTP transport that includes digest auth
- enable the client
- perform the get request
- extract the request body into a stream
- decode the stream into the mapped data structure (from step 1)
- use the information
Here’s the sample:
package main
import (
“fmt”
digest “code.google.com/p/mlab-ns2/gae/ns/digest”
“encoding/json”
)
// the struct maps to the JSON automatically with the added meta data
type Deployment struct {
ID int `json:”id”`
State int `json:”state”`
Name string `json:”name”`
Description string `json:”description”`
System bool `json:”system”`
ParentID int64 `json:”parent_id”`
CreatedAt string `json:”created_at”`
UpdatedAt string `json:”updated_at”`
}
func main() {
// setup a transport to handle disgest
transport := digest.NewTransport(“crowbar”, “password”)
// initialize the client
client, err := transport.Client()
if err != nil {
return err
}
// make the call (auth will happen)
resp, err := client.Get(“http://127.0.0.1:3000/api/v2/deployments”)
if err != nil {
return err
}
defer resp.Body.Close()
// magic of the structure definition will map automatically
var d []Deployment // it’s an array returned, so we need an array here.
err = json.NewDecoder(resp.Body).Decode(&d)
// print results
fmt.Printf(“Header:%s\n”, resp.Header[“Content-Type”])
fmt.Printf(“Code:%s\n”, resp.Status)
fmt.Printf(“Name:%s\n”, d[0].Name)
}
PS: I’m doing this for the Digital Rebar API driver because it uses REST and Digest. We’re actively maintaining it there if you want the latest.