DEV Community

Cover image for πŸ’« Aerospike URL - Turn connection string into Aerospike DB client
Serhii
Serhii

Posted on • Edited on

πŸ’« Aerospike URL - Turn connection string into Aerospike DB client

✌️ Hello devs!

In this blog post, I would like to share my recent open-source initiative that has been built to provide developers with another way to connect to the Aerospike DB.

πŸ”— Aerospike URL

You can go ahead and check the repo:

GitHub logo tiptophelmet / aerospike-url

πŸ’« Parses URL connection string into Aerospike client.

aerospike-url

πŸ’« Parses URL connection string into Aerospike client.

πŸ‘‡ Usage

πŸ”— Connection string format

aerospike://aerouser001:aerouserpassw123@127.0.0.1:3000/my-aerospike-namespace?auth_mode=auth_mode_internal&timeout=10s&idle_timeout=3s&max_error_rate=50

βš™οΈ Parse connection string into Aerospike client factory

package main
import (
    "fmt"

    aerospikeurl "github.com/tiptophelmet/aerospike-url"
    aero "github.com/aerospike/aerospike-client-go/v6"
)

// Use aerospikeurl to build Aerospike client from URL
func buildClientFromURL(url string) *aero.Client {
    clientFactory, err := aerospikeurl.Parse(url)
    if err != nil {
        panic(err)
    }

    client, err := clientFactory.BuildClient()
    if err != nil {
        panic(err)
    }

    return client
}

// This is only for this example.
// Please handle errors properly.
func panicOnError(err error) {
    if err != nil {
        panic(err)
    }
}

// Use Aerospike client as usual
func main() {
    url := "aerospike://aerouser001:aerouserpassw123@127.0.0.1:3000/my-aerospike-namespace?auth_mode=auth_mode_internal&timeout=10s&idle_timeout=3s&max_error_rate=50"

    client := buildClientFromURL(url)
    defer client.Close()

    key, err := aero.NewKey("test", "aerospike", "key")
    panicOnError(err)

    // define some bins with data
    bins := aero.BinMap{
        "bin1": 42,
        "bin2": "An elephant is a mouse with an operating system",
        "bin3": []interface{}{"Go", 2009},
    }

    // write the bins
…

Published Go package is here as well:
https://pkg.go.dev/github.com/tiptophelmet/aerospike-url


🀠 Motivation

During my work with various in-memory key-value stores like Redis and Memcached I always had an option to connect using URL connection string like redis://myusername:mypassword@redis.example.com:6379/1 or memcached://memcached.example.com:11211.

This way I can provide a whole URL connection string from an environment variable, like REDIS_URL or MEMCACHED_CONN_STRING, directly when initializing DB client. It's an architectural requirement I should stick to.

I discovered Aerospike DB and its hybrid model of storing indexes in RAM, while still persisting data on a disk.

It matched product business needs and I started looking for an option to connect using URL & I discovered the official Aerospike Go Client supports only 3 options for establishing a DB connection:

No way! I still needed to connect to Aerospike using URL.
Given my requirement and time estimates - I decided to create a new Go package that would solve my task!


πŸ’‘ How it works

TL;DR
πŸ’« Adjust & pass this URL into aerospikeurl.Parse and your connection will be up & running:
aerospike://aerouser001:aerouserpassw123@127.0.0.1:3000/my-aerospike-namespace?auth_mode=auth_mode_internal&timeout=10s&idle_timeout=3s&max_error_rate=50


Specify user:passw after aerospike://, after @ specify Aerospike host 127.0.0.1:3000, then put your Aerospike namespace /my-aerospike-namespace.

Query parameters are aerospike.ClientPolicy properties.

If query parameters are specified, client is created using aerospike.NewClientWithPolicy, otherwise aerospike.NewClient.


πŸ“„ Example

package main

import (
    "fmt"

    aerospikeurl "github.com/tiptophelmet/aerospike-url"
    aero "github.com/aerospike/aerospike-client-go/v6"
)

// Use aerospikeurl to build Aerospike client from URL
func buildClientFromURL(url string) *aero.Client {
    clientFactory, err := aerospikeurl.Parse(url)
    if err != nil {
        panic(err)
    }

    client, err := clientFactory.BuildClient()
    if err != nil {
        panic(err)
    }

    return client
}

// This is only for this example.
// Please handle errors properly.
func panicOnError(err error) {
    if err != nil {
        panic(err)
    }
}

// Use Aerospike client as usual
func main() {
    url := "aerospike://aerouser001:aerouserpassw123@127.0.0.1:3000/my-aerospike-namespace?auth_mode=auth_mode_internal&timeout=10s&idle_timeout=3s&max_error_rate=50"

    client := buildClientFromURL(url)
    defer client.Close()

    key, err := aero.NewKey("test", "aerospike", "key")
    panicOnError(err)

    // define some bins with data
    bins := aero.BinMap{
        "bin1": 42,
        "bin2": "An elephant is a mouse with an operating system",
        "bin3": []interface{}{"Go", 2009},
    }

    // write the bins
    err = client.Put(nil, key, bins)
    panicOnError(err)

    // read it back!
    rec, err := client.Get(nil, key)
    panicOnError(err)

    fmt.Printf("Record bins: %v", rec.Bins)

    // delete the key, and check if key exists
    existed, err := client.Delete(nil, key)
    panicOnError(err)

    fmt.Printf("Record existed before delete? %v\n", existed)
}
Enter fullscreen mode Exit fullscreen mode

🏷️ Project stage

Aerospike URL is in its early stage and suggestions are welcome!
Feel free to create issues or pull requests in the Github repo

Top comments (0)