Calling the MongoDB Atlas API - How to do it from Go

Facebook ShareLinkedin ShareReddit ShareTwitter Share

After last week's article on how to access the Atlas API with Node, Python, and Ruby, I was asked why didn't I mention Go (among other languages). Well, no need to worry. Here's an extra slab of Atlas API access in Go.

Now, one thing to note with the Go culture is there's a strong bias towards using the system libraries if you can. So for this example, we're only using the standard HTTP package. The thing is there is no support currently for digest authentication in the standard HTTP package - there is a proposal to add it but it's not on the planning radar yet. Luckily, there's a number of digest authentication implementations in the Go ecosystem and for this example, we'll use xinsnake's go-http-digest-auth-client. So let's dive in to...

The Obligatory Preamble

package main

import (
    "encoding/json"
    "fmt"
    dac "github.com/xinsnake/go-http-digest-auth-client"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

const baseURL = "https://cloud.mongodb.com/api/atlas/v1.0/"

The preamble on this code imports all the essential packages we'll need; some io, some JSON encoding, some formatting, and the aforementioned Digest Authentication package. We also set the base URL for the MongoDB Atlas API. In this example, as with the previous article, we'll be querying that to get build information about the API.

Getting going

Now we go into the main function and first thing we need to do is get the environment variables for ATLAS_USER and ATLAS_USER_KEY so we have credentials to log in.

func main() {
    username, usernameexists := os.LookupEnv("ATLAS_USER")
    userkey, userkeyexists := os.LookupEnv("ATLAS_USER_KEY")

    if !usernameexists || !userkeyexists {
        log.Fatalln("Env vars missing")
    }

I recommend always getting environment variables with LookupEnv as it's easier to see when they aren't set.

Now we are ready to set up the HTTP digest auth client:

    t := dac.NewTransport(username, userkey)

This initializes a transport we'll use to send our requests over, so the next thing we'll need is a request.

    req, err := http.NewRequest("GET", baseURL, nil)

Now we can use the transport to send the request on a round trip. The transport will take care of the authentication so all we need to worry about is checking the error state.

    resp, err := t.RoundTrip(req)
    if err != nil {
        log.Fatalln(err)
    }

Finishing Up

And the rest of the example is pretty standard. We need to read the body from the response.

    defer resp.Body.Close()

    body, readErr := ioutil.ReadAll(resp.Body)
    if readErr != nil {
        log.Fatalln(readErr)
    }

And then decode the JSON in that returned string. This example just decodes it into an interface{} which is fine for testing out the API like this. You'll want to decode into an appropriate structure if you are looking to put the response to work.

        var response interface{}

        if err := json.Unmarshal(body, &response); err != nil {
        log.Fatal(err)
    }

Finally, we turn it all back into a pretty printed JSON string and print it out.

    s, _ := json.MarshalIndent(response, "", " ")

    fmt.Println(string(s))
}

Which gives us…

Atlas API Go example

Now all you have to do is refer to the Atlas API documentation to see what REST endpoints you can call on to manage your MongoDB Atlas deployments.

You can find the code for this example in https://github.com/mongodb-developer/atlasgo.