Basic Redis Examples with Go

Redis is pretty great. It is the #1 most loved database for the second year in a row, according to a recent Stack Overflow survey. I decided it was high time I taught myself how to use it with Go.

There are a number of libraries in the Go ecosystem for Redis, but the two most popular are go-redis and redigo. Each library has a decent amount of stars, contributors, etc. but from what I can tell redigo seems to have a slight edge in terms of documentation and community acceptance. For instance, the mighty Redis Labs, has a couple of posts describing interacting with Redis via Go using redigo — it’s not a direct endorsement, but pretty close… I tried both libraries actually, but found redigo was better documented. That said, in order to get up and running quickly with redigo, having to troll through godoc was a bit cumbersome (I’m still getting my head around analyzing godoc TBH). In this post, I’ll attempt to give some simple examples for redigo that may prove helpful to some.

Below I take you through creating a connection pool, testing connectivity via the PING command, adding a simple Key:Value pair via the SET command, retrieving a given value given the GET command and finally storing a struct as JSON using the SET command and retrieving the same struct with the GET command.

TL;DR — For the full main.go with all the examples below, you can find them here.

POOL

Use the Get method of the Pool object to grab a connection from the pool. Per the redigo documentation, “The application must call the connection Close method when the application is done with the connection.”

func main() {    pool := newPool()
conn := pool.Get()
defer conn.Close()
err := ping(conn)
if err != nil {
fmt.Println(err)
}
...

PING

To break down what’s happening here — the function takes in a redis Conn type (connection). We are calling the Do method of Conn, which takes a Redis command as it’s first argument. The redigo client communicates to Redis using Redis’ RESP protocol. Redis then responds with one of several types (Simple Strings, Errors, Integers, Bulk Strings and Arrays), which are mapped to Go types. The response from the Do method does not give back the specific Go type though, but rather an interface{} type. We can use a type assertion to determine the response type from the Do method, but seeing as we know from the Redis documentation that the Return Value from PING is a simple string, we can use one of redigo’s handy helper functions (redis.String) to perform a type conversion to string for us.

For illustrative purposes in my example above, I executed the helper redis.String function separately from the Do method as I found it easier to understand on my first pass. In reality, you’ll use the redigo provided helper functions to wrap your Do method calls (provided you know the response type), as I have done in the example below. Any remaining examples will use this shortened form where appropriate.

SET

// set executes the redis SET command
func set(c redis.Conn) error {
_, err := c.Do("SET", "Favorite Movie", "Repo Man")
if err != nil {
return err
}
_, err = c.Do("SET", "Release Year", 1984)
if err != nil {
return err
}
return nil
}

GET

STRUCT (SET)

For my purposes, I am ok with just storing the data as an object in its entirety and thus decided to store my data as JSON using the SET command.

The example below shows storing a user, with username “otto”, with a key of “user:otto”. Use json.Marshal to serialize your object to JSON and store the serialized version as the value.

STRUCT (GET)

{Username:otto MobileID:1234567890 Email:ottoM@repoman.com FirstName:Otto LastName:Maddox}

That’s it for now. Keep in mind, I wrote this main and these little functions in a somewhat non-idiomatic way just to aid in the examples, you should streamline this in a real app.

I also created a similar main.go for the go-redis client, that you can find here. For go-redis, storing structs as Redis hashes is easier, as you can pass a map of strings type to the HMSET command.

Go enthusiast; Loyalty/CRM Technology Leader; Drummer; Vinyl geek; Husband/Dad