golang: Encode/Decode arbitrary JSON

Just a quick post in case I forget how to do this in future. I had a use case for working with reading arbitrary JSON from a file and parsing it using Golang, which meant that the recommended way of using structs wasn’t suitable.

json.Marshal

The first thing to do was marshal a custom data structure into being a JSON string using json.Marshal. This was fairly straightforward to do:

cacheContent := map[string]interface{}{
    "foo": "bar",
    "baz": map[string]interface{}{
        "bee": "boo",
    },
}

str, err := json.Marshal(cacheContent)
if err != nil {
    fmt.Println("Error encoding JSON")
    return
}

fmt.Println(string(str))
# => {"baz":{"bee":"boo"},"foo":"bar"}

json.Unmarshal

json.Unmarshal was the tough one to work out. As it turns out, all you need to do is define a map of string => interface and then unmarshal into this structure. Go will take care of the rest.

# Using the "str" variable that we created using json.Marshal earlier
var x map[string]interface{}
json.Unmarshal([]byte(str), &x)
fmt.Println("%v", x)
# => %v map[baz:map[bee:boo] foo:bar]


# Using some hand crafted JSON. This could come from a file, web service, anything
str2 := "{\"foo\":[1,2,3]}"

var y map[string]interface{}
json.Unmarshal([]byte(str2), &y)

fmt.Println("%v", y)
# => %v map[foo:[1 2 3]]

Once the data is un-marshalled, you can access it as follows:

fmt.Printf("%v", str["baz"].(map[string]interface{})["bee"})
# => "boo"

As we're un-marshalling into an interface, we need to inform go what data type each key is before we can perform operations on it. This is what the .(map[string]interface{}) does

golang: invalid operation: someVar == “” (mismatched types *string and string)

I was trying to see if a value was empty in a golang script I was writing, when I came across an odd error message:

invalid operation: someVar == "" (mismatched types *string and string)

It turns out that the following code doesn’t return a simple string, but an instance of flag.String

someVar := flag.String("somevar", "", "this is a random flag")

To perform the comparison, you need to use a pointer to it as follows:

if *someVar != "" {
    // Do this
}

Working with Memcached via CLI

A lot of the time when I’m working on a project that uses memcached, I’ll want to have a look at the data in the cache without using my application to make sure that it’s doing what I expect. I didn’t expect that wanting to list all keys on a memcached server was such a big request, but it looked like there wasn’t any easy way to do it.

I did start a project named mempp to provide a CLI friendly interface to memcached via the Python bindings, but as it turns out you don’t even need this. libmemcached ships with everything you need.

First, you’ll need to install libmemcached-tools

sudo apt-get install libmemcached-tools

Then, if you want to list all keys stored on a server, you can use memcdump

$ memcdump --servers localhost:11211
key_one
key_two_123

If you want to see the values of those keys, use memccat

$ memccat --servers localhost:11211 key_one
FooBar

If you want to remove a key, use memcrm

$ memcrm --servers localhost:11211 key_one

With a combination of memcdump and memccat, plus memcrm you can poke around your memcached instance without needing to use telnet or list slabs or anything like that, which most posts advise you to do.