Install and Start Using the Go SDK with Couchbase Server

    +

    Hello Couchbase

    On this page we show you how to quickly get up and running — installing the Couchbase Go SDK, and trying out the Hello World code example against Couchbase Capella, or against a local Couchbase cluster.

    We will go through the code sample step by step, but for those in a hurry to see it, here it is:

    • Couchbase Capella Sample

    • Local Couchbase Server

    To connect to Couchbase Capella, be sure to get the correct endpoint as well as user, password and bucket name.

    package main
    
    import (
    	"fmt"
    	"log"
    	"time"
    
    	"github.com/couchbase/gocb/v2"
    )
    
    
    func main() {
    	// Uncomment following line to enable logging
    	// gocb.SetLogger(gocb.VerboseStdioLogger())
    
    	// Update this to your cluster details
    	endpoint := "cb.<your-endpoint>.cloud.couchbase.com"
    	bucketName := "travel-sample"
    	username := "username"
    	password := "Password123!"
    
    	// Initialize the Connection
    	cluster, err := gocb.Connect("couchbases://"+endpoint, gocb.ClusterOptions{
    		Authenticator: gocb.PasswordAuthenticator{
    			Username: username,
    			Password: password,
    		},
    	})
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	bucket := cluster.Bucket(bucketName)
    
    	err = bucket.WaitUntilReady(5*time.Second, nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Get a reference to the default collection, required for older Couchbase server versions
    	// col := bucket.DefaultCollection()
    
    	col := bucket.Scope("tenant_agent_00").Collection("users")
    
    	type User struct {
    		Name      string   `json:"name"`
    		Email     string   `json:"email"`
    		Interests []string `json:"interests"`
    	}
    
    	// Create and store a Document
    	_, err = col.Upsert("u:kingarthur",
    		User{
    			Name:      "Arthur",
    			Email:     "kingarthur@couchbase.com",
    			Interests: []string{"Holy Grail", "African Swallows"},
    		}, nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Get the document back
    	getResult, err := col.Get("u:kingarthur", nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	var inUser User
    	err = getResult.Content(&inUser)
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Printf("User: %v\n", inUser)
    
    	// Perform a N1QL Query
    	queryResult, err := cluster.Query(
    		fmt.Sprintf("SELECT name FROM `%s` WHERE $1 IN interests", bucketName),
    		&gocb.QueryOptions{PositionalParameters: []interface{}{"African Swallows"}},
    	)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Print each found Row
    	for queryResult.Next() {
    		var result interface{}
    		err := queryResult.Row(&result)
    		if err != nil {
    			log.Fatal(err)
    		}
    		fmt.Println(result)
    	}
    
    	if err := queryResult.Err(); err != nil {
    		log.Fatal(err)
    	}
    }
    package main
    
    import (
    	"crypto/x509"
    	"fmt"
    	"io/ioutil"
    	"log"
    	"time"
    
    	"github.com/couchbase/gocb/v2"
    )
    
    func main() {
    	// Uncomment following line to enable logging
    	// gocb.SetLogger(gocb.VerboseStdioLogger())
    
    	// Update this to your cluster details
    	bucketName := "travel-sample"
    	username := "Administrator"
    	password := "password"
    
    	p, err := ioutil.ReadFile("path/to/ca.pem")
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	roots := x509.NewCertPool()
    	roots.AppendCertsFromPEM(p)
    
    	// Initialize the Connection
    	cluster, err := gocb.Connect("couchbases://127.0.0.1", gocb.ClusterOptions{
    		Authenticator: gocb.PasswordAuthenticator{
    			Username: username,
    			Password: password,
    		},
    		SecurityConfig: gocb.SecurityConfig{
    			TLSRootCAs: roots,
    			// WARNING: Do not set this to true in production, only use this for testing!
    			// TLSSkipVerify: true,
    		},
    	})
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	bucket := cluster.Bucket(bucketName)
    
    	err = bucket.WaitUntilReady(5*time.Second, nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Get a reference to the default collection, required for older Couchbase server versions
    	// col := bucket.DefaultCollection()
    
    	col := bucket.Scope("tenant_agent_00").Collection("users")
    
    	type User struct {
    		Name      string   `json:"name"`
    		Email     string   `json:"email"`
    		Interests []string `json:"interests"`
    	}
    
    	// Create and store a Document
    	_, err = col.Upsert("u:kingarthur",
    		User{
    			Name:      "Arthur",
    			Email:     "kingarthur@couchbase.com",
    			Interests: []string{"Holy Grail", "African Swallows"},
    		}, nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Get the document back
    	getResult, err := col.Get("u:kingarthur", nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	var inUser User
    	err = getResult.Content(&inUser)
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Printf("User: %v\n", inUser)
    
    	// Perform a N1QL Query
    	queryResult, err := cluster.Query(
    		fmt.Sprintf("SELECT name FROM `%s` WHERE $1 IN interests", bucketName),
    		&gocb.QueryOptions{PositionalParameters: []interface{}{"African Swallows"}},
    	)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Print each found Row
    	for queryResult.Next() {
    		var result interface{}
    		err := queryResult.Row(&result)
    		if err != nil {
    			log.Fatal(err)
    		}
    		fmt.Println(result)
    	}
    
    	if err := queryResult.Err(); err != nil {
    		log.Fatal(err)
    	}
    }

    As well as the Go SDK (see below), and a running instance of Couchbase Server, you will need to load up the Travel Sample Bucket using either the Web interface or the command line.

    The Couchbase Capella free trial version comes with the Travel Sample Bucket, and its Query indexes, loaded and ready.

    Quick Installation

    Version 2 of the Go SDK has added support for Go Modules. You can use go get to download the SDK:

    $ go get github.com/couchbase/gocb/v2@v2.5.0

    More details on installation can be found here.

    In line with the Golang project, we support both the current, and the previous, versions of Go.

    Step by Step

    At this point we want to transition from the terminal to your code editor of choice.

    Let’s now create an empty file named main.go and walk through adding code step-by-step:

    • Connect to a single node cluster, bucket, and collection;

    • Add and retrieve a new document;

    • Look up (SQL-type query) the new document by attribute value.

    Prerequisites

    Here are all of the imports that you will need to run the sample code.

    package main
    
    import (
    	"fmt"
    	"log"
    	"time"
    
    	"github.com/couchbase/gocb/v2"
    )

    Now, create an empty main() function.

    func main() {
    	// add code here...
    }

    We will update this function as we go along the steps in this guide.

    Connection

    The basic connection details that you’ll need are given below — for more background information, refer to the Managing Connections page.

    In the main() function, add the following:

    • Couchbase Capella

    • Local Couchbase Server

    Couchbase Capella requires mandatory use of TLS (Transport Layer Security). As of Go SDK version 2.5.0, the standard certificate required to connect to a Capella cluster is automatically included with no additional configuration.
    // Update this to your cluster details
    endpoint := "cb.<your-endpoint>.cloud.couchbase.com"
    bucketName := "travel-sample"
    username := "username"
    password := "Password123!"
    
    // Initialize the Connection
    cluster, err := gocb.Connect("couchbases://"+endpoint, gocb.ClusterOptions{
    	Authenticator: gocb.PasswordAuthenticator{
    		Username: username,
    		Password: password,
    	},
    })
    if err != nil {
    	log.Fatal(err)
    }

    Couchbase Capella uses Roles to control user access to database resources. For the purposes of this example, we can use the Organization Owner role automatically assigned to a user account during installation of the Capella cluster. This role grants full access to a Capella organization, including full data access to all projects and clusters. In a production scenario, we strongly recommend setting up users with more granular access roles as a best practice.

    For the SDK client to access cluster data, you will need to set up credentials for your database by following these steps.

    // Update this to your cluster details
    bucketName := "travel-sample"
    username := "Administrator"
    password := "password"
    
    p, err := ioutil.ReadFile("path/to/ca.pem")
    if err != nil {
    	log.Fatal(err)
    }
    
    roots := x509.NewCertPool()
    roots.AppendCertsFromPEM(p)
    
    // Initialize the Connection
    cluster, err := gocb.Connect("couchbases://127.0.0.1", gocb.ClusterOptions{
    	Authenticator: gocb.PasswordAuthenticator{
    		Username: username,
    		Password: password,
    	},
    	SecurityConfig: gocb.SecurityConfig{
    		TLSRootCAs: roots,
    		// WARNING: Do not set this to true in production, only use this for testing!
    		// TLSSkipVerify: true,
    	},
    })
    if err != nil {
    	log.Fatal(err)
    }

    Couchbase uses Role Based Access Control (RBAC) to control access to resources. For the purposes of this example, we are connecting to Couchbase using the Full Admin role created during the installation of our Couchbase Server.

    Couchbase RBAC is fully described in the Manage Users, Groups, and Roles page.

    Following successful authentication, the bucket can be opened:

    bucket := cluster.Bucket(bucketName)
    
    err = bucket.WaitUntilReady(5*time.Second, nil)
    if err != nil {
    	log.Fatal(err)
    }
    We are working with the travel-sample data bucket. If you are not, update the bucketName variable used in the example with your own.

    The 2.5 SDK supports full integration with the Collections feature introduced in Couchbase Server 7.0. Collections allow documents to be grouped by purpose or theme, according to a specified Scope. Here we will use the users collection within the tenant_agent_00 scope from travel-sample bucket as an example.

    // Get a reference to the default collection, required for older Couchbase server versions
    // col := bucket.DefaultCollection()
    
    col := bucket.Scope("tenant_agent_00").Collection("users")

    The code shows how you would use a named collection and scope. A named or default collection will provide the same functionality as bucket-level operations did in previous versions of Couchbase Server.

    The DefaultCollection must be used when connecting to a 6.6 cluster or earlier.

    Document Addition and Retrieval

    Let’s create a struct in our application that we can add to our travel-sample bucket that conforms to the structure of a document of type user.

    type User struct {
    	Name      string   `json:"name"`
    	Email     string   `json:"email"`
    	Interests []string `json:"interests"`
    }

    Document operations, such as storing and retrieving documents, can be done using Collection.Upsert() and Collection.Get(). Simply pass the key (and value, if applicable) to the relevant methods.

    The following function will upsert a document into the database:

    // Create and store a Document
    _, err = col.Upsert("u:kingarthur",
    	User{
    		Name:      "Arthur",
    		Email:     "kingarthur@couchbase.com",
    		Interests: []string{"Holy Grail", "African Swallows"},
    	}, nil)
    if err != nil {
    	log.Fatal(err)
    }

    Now, let’s retrieve that document using a key-value operation. The following function runs a get for a document key and logs out the result in our console:

    // Get the document back
    getResult, err := col.Get("u:kingarthur", nil)
    if err != nil {
    	log.Fatal(err)
    }
    
    var inUser User
    err = getResult.Content(&inUser)
    if err != nil {
    	log.Fatal(err)
    }
    fmt.Printf("User: %v\n", inUser)

    SQL++ Lookup

    Couchbase N1QL queries are performed by invoking Cluster.Query(). In the code below we will query Couchbase to retrieve users with a particular interest and print the results.

    // Perform a N1QL Query
    queryResult, err := cluster.Query(
    	fmt.Sprintf("SELECT name FROM `%s` WHERE $1 IN interests", bucketName),
    	&gocb.QueryOptions{PositionalParameters: []interface{}{"African Swallows"}},
    )
    if err != nil {
    	log.Fatal(err)
    }
    
    // Print each found Row
    for queryResult.Next() {
    	var result interface{}
    	err := queryResult.Row(&result)
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Println(result)
    }
    
    if err := queryResult.Err(); err != nil {
    	log.Fatal(err)
    }

    Execute!

    Now we can run our code using the following command:

    $ go run main.go

    The results you should expect are as follows:

    User: {Arthur kingarthur@couchbase.com [Holy Grail African Swallows]}
    map[name:Arthur]

    Next Steps

    Now you’re up and running, try one of the following:

    Additional Resources

    The API reference is generated for each release and can be found here. Older API references are linked from their respective sections in the Release Notes.

    The Migrating from SDK2 API (Go 1.x) to API 3 page (Go 2.x SDK) highlights the main differences to be aware of when migrating your code.

    Couchbase welcomes community contributions to the Go SDK. The Go SDK source code is available on GitHub.

    Troubleshooting