Documentation

Build Status Release Docs

IBM Cloudant Go SDK Version 0.0.33

IBM Cloudant Go SDK is a client library that interacts with the IBM Cloudant APIs.

Disclaimer: This SDK is being released initially as a pre-release version. Changes might occur which impact applications that use this SDK.

Table of Contents

Overview

The IBM Cloudant Go SDK allows developers to programmatically interact with IBM Cloudant with the help of the cloudantv1 package.

Features

The purpose of this Go SDK is to wrap most of the HTTP request APIs provided by Cloudant and supply other functions to ease the usage of Cloudant. This SDK should make life easier for programmers to do what’s really important to them: developing software.

Reasons why you should consider using Cloudant Go SDK in your project:

  • Supported by IBM Cloudant.
  • Server compatibility with:
  • Includes all the most popular and latest supported endpoints for applications.
  • Handles the authentication.
  • Familiar user experience with IBM Cloud SDKs.
  • Flexibility to use either built-in models or byte-based requests and responses for documents.
  • HTTP2 support for higher performance connections to IBM Cloudant.
  • Perform requests synchronously.
  • Safe for concurrent use by multiple goroutines.
  • Transparently compresses request and response bodies.

Prerequisites

  • A Cloudant service instance or a CouchDB server.
  • Go version 1.15 or 1.16.

Installation

The current version of this SDK: 0.0.33

There are a few different ways to download and install the Cloudant Go SDK project for use by your Go application:

go get command

Use this command to download and install the SDK to allow your Go application to use it:

go get -u github.com/IBM/cloudant-go-sdk/cloudantv1

Go modules

If your application is using Go modules, you can add a suitable import to your Go application, like this:

import (
  "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

then run go mod tidy to download and install the new dependency and update your Go application's go.mod file.

dep dependency manager

If your application is using the dep dependency management tool, you can add a dependency to your Gopkg.toml file. Here is an example:

[[constraint]]
  name = "github.com/IBM/cloudant-go-sdk"
  version = "0.0.33"

then run dep ensure.

Authentication

This library requires some of your Cloudant service credentials to authenticate with your account.

  1. IAM, COUCHDB_SESSION, BASIC or NOAUTH authentication type.
    1. IAM authentication is highly recommended when your back-end database server is Cloudant. This authentication type requires a server-generated apikey instead of a user-given password. You can create one here.
    2. Session cookie (COUCHDB_SESSION) authentication is recommended for Apache CouchDB or for Cloudant when IAM is unavailable. It exchanges username and password credentials for an AuthSession cookie from the /_session endpoint.
    3. Basic (or legacy) authentication is a fallback for both Cloudant and Apache CouchDB back-end database servers. This authentication type requires the good old username and password credentials.
    4. Noauth authentication does not require credentials. Note that this authentication type only works with queries against a database with read access for everyone.
  2. The service url.

There are several ways to set these properties:

  1. As environment variables
  2. The programmatic approach
  3. With an external credentials file

Authentication with environment variables

IAM authentication

For Cloudant IAM authentication, set the following environmental variables by replacing the <url> and <apikey> with your proper service credentials. There is no need to set CLOUDANT_AUTH_TYPE to IAM because it is the default.

CLOUDANT_URL=<url>
CLOUDANT_APIKEY=<apikey>

Session cookie authentication

For COUCHDB_SESSION authentication, set the following environmental variables by replacing the <url>, <username> and <password> with your proper service credentials.

CLOUDANT_AUTH_TYPE=COUCHDB_SESSION
CLOUDANT_URL=<url>
CLOUDANT_USERNAME=<username>
CLOUDANT_PASSWORD=<password>

Basic authentication

For Basic authentication, set the following environmental variables by replacing the <url>, <username> and <password> with your proper service credentials.

CLOUDANT_AUTH_TYPE=BASIC
CLOUDANT_URL=<url>
CLOUDANT_USERNAME=<username>
CLOUDANT_PASSWORD=<password>

Note: We recommend that you use IAM for Cloudant and Session for CouchDB authentication.

Authentication with external configuration

To use an external configuration file, the Cloudant API docs, or the general SDK usage information will guide you.

Programmatic authentication

To learn more about how to use programmatic authentication, see the related documentation in the Cloudant API docs or in the Go SDK Core document about authentication.

Using the SDK

For general IBM Cloud SDK usage information, please see IBM Cloud SDK Common.

Code examples

The following code examples authenticate with the environment variables.

1. Retrieve information from an existing database

Note: This example code assumes that animaldb database does not exist in your account.

This example code gathers information about an existing database hosted on the https://examples.cloudant.com/ service url. To connect, you must extend your environment variables with the service url and authentication type to use NOAUTH authentication while you connect to the animaldb database. This step is necessary for the SDK to distinguish the EXAMPLES custom service name from the default service name which is CLOUDANT.

Cloudant environment variable naming starts with a service name prefix that identifies your service. By default this is CLOUDANT, see the settings in the authentication with environment variables section.

If you would like to rename your Cloudant service from CLOUDANT, you must use your defined service name as the prefix for all Cloudant related environment variables. The code block below provides an example of instantiating a user-defined EXAMPLES service name.

EXAMPLES_URL=https://examples.cloudant.com
EXAMPLES_AUTH_TYPE=NOAUTH

Once the environment variables are set, you can try out the code examples.

package main

import (
	"encoding/json"
	"fmt"

	"github.com/IBM/cloudant-go-sdk/cloudantv1"
)

func main() {
	// 1. Create a Cloudant client with "EXAMPLES" service name ============
	client, err := cloudantv1.NewCloudantV1UsingExternalConfig(
		&cloudantv1.CloudantV1Options{
			ServiceName: "EXAMPLES",
		},
	)
	if err != nil {
		panic(err)
	}
	// 2. Get server information ===========================================
	serverInformationResult, _, err := client.GetServerInformation(
		client.NewGetServerInformationOptions(),
	)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Server Version: %s\n", *serverInformationResult.Version)
	// 3. Get database information for "animaldb" ==========================
	dbName := "animaldb"
	databaseInformationResult, _, err := client.GetDatabaseInformation(
		client.NewGetDatabaseInformationOptions(
			dbName,
		),
	)
	if err != nil {
		panic(err)
	}
	// 4. Show document count in database ==================================
	fmt.Printf("Document count in \"%s\" database is %d.\n",
		*databaseInformationResult.DbName,
		*databaseInformationResult.DocCount)
	// 5. Get zebra document out of the database by document id ============
	documentAboutZebraResult, _, err := client.GetDocument(
		client.NewGetDocumentOptions(
			dbName,
			"zebra",
		),
	)
	if err != nil {
		panic(err)
	}
	// 6. Print out the Document content ===================================
	aboutZebraBuffer, _ := json.MarshalIndent(documentAboutZebraResult, "", "  ")
	fmt.Println(string(aboutZebraBuffer))
}

When you run the code, you see a result similar to the following output.

Server Version: 2.1.1
Document count in "animaldb" database is 11.
{
  "_id": "zebra",
  "_rev": "3-750dac460a6cc41e6999f8943b8e603e",
  "class": "mammal",
  "diet": "herbivore",
  "max_length": 2.5,
  "max_weight": 387,
  "min_length": 2,
  "min_weight": 175,
  "wiki_page": "http://en.wikipedia.org/wiki/Plains_zebra"
}

2. Create your own database and add a document

Note: This example code assumes that orders database does not exist in your account.

Now comes the exciting part, you create your own orders database and add a document about Bob Smith with your own IAM or Basic service credentials.

Create code example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/IBM/cloudant-go-sdk/cloudantv1"
)

func main() {
	// 1. Create a client with `CLOUDANT` default service name =============
	client, err := cloudantv1.NewCloudantV1UsingExternalConfig(
		&cloudantv1.CloudantV1Options{},
	)
	if err != nil {
		panic(err)
	}

	// 2. Create a database ================================================
	exampleDbName := "orders"

	putDatabaseResult, putDatabaseResponse, err := client.PutDatabase(
		client.NewPutDatabaseOptions(exampleDbName),
	)
	if err != nil {
		if putDatabaseResponse.StatusCode == 412 {
			fmt.Printf("Cannot create \"%s\" database, it already exists.\n",
				exampleDbName)
		} else {
			panic(err)
		}
	}

	if putDatabaseResult != nil && *putDatabaseResult.Ok {
		fmt.Printf("\"%s\" database created.\n", exampleDbName)
	}

	// 3. Create a document ================================================
	// 3.1. Create a document object with "example" id
	exampleDocID := "example"
	exampleDocument := cloudantv1.Document{
		ID: &exampleDocID,
	}

	// 3.2. Add "name" and "joined" fields to the document
	exampleDocument.SetProperty("name", "Bob Smith")
	exampleDocument.SetProperty("joined", "2019-01-24T10:42:99.000Z")

	// 3.3. Save the document in the database
	postDocumentOption := client.NewPostDocumentOptions(
		exampleDbName,
	).SetDocument(&exampleDocument)

	postDocumentResult, _, err := client.PostDocument(postDocumentOption)
	if err != nil {
		panic(err)
	}

	// 3.4. Keep track of the revision number from the `example` document object
	exampleDocument.Rev = postDocumentResult.Rev

	// 3.5. Print out the document content
	exampleDocumentContent, _ := json.MarshalIndent(exampleDocument, "", "  ")
	fmt.Printf("You have created the document:\n%s\n", string(exampleDocumentContent))
}
When you run the code, you see a result similar to the following output.
"orders" database created.
You have created the document:
{
  "_id": "example",
  "_rev": "1-1b403633540686aa32d013fda9041a5d",
  "joined": "2019-01-24T10:42:99.000Z",
  "name": "Bob Smith"
}

3. Update your previously created document

Note: This example code assumes that you have created both the orders database and the example document by running the previous example code successfully. Otherwise, the following error message occurs, "Cannot update document because either 'orders' database or 'example' document was not found."

Update code example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/IBM/cloudant-go-sdk/cloudantv1"
)

func main() {
	// 1. Create a client with `CLOUDANT` default service name =============
	client, err := cloudantv1.NewCloudantV1UsingExternalConfig(
		&cloudantv1.CloudantV1Options{},
	)
	if err != nil {
		panic(err)
	}

	// 2. Update the document ==============================================
	exampleDbName := "orders"
	exampleDocID := "example"

	// 2.1. Get the document if it previously existed in the database
	document, getDocumentResponse, err := client.GetDocument(
		client.NewGetDocumentOptions(
			exampleDbName,
			exampleDocID,
		),
	)
	if err != nil {
		if getDocumentResponse.StatusCode == 404 {
			fmt.Printf("Cannot update document because "+
				"either \"%s\"  database or \"%s\" document was not found.\n",
				exampleDbName,
				exampleDocID)
		} else {
			panic(err)
		}
	}

	if document != nil {
		// 2.2. Make some modifiction in the document content
		// 2.2.1. Add Bob Smith's address to the document
		document.SetProperty("address", "19 Front Street, Darlington, DL5 1TY")
		// 2.2.2. Remove the joined property from document object
		delete(document.GetProperties(), "joined")

		// 2.3. Update the document in the database
		postDocumentOption := client.NewPostDocumentOptions(
			exampleDbName,
		).SetDocument(document)

		postDocumentResult, _, err := client.PostDocument(
			postDocumentOption,
		)
		if err != nil {
			panic(err)
		}

		// 2.4. Keep track the revision number of the document object
		document.Rev = postDocumentResult.Rev

		// 2.5. Print out the new document content
		documentContent, _ := json.MarshalIndent(document, "", "  ")
		fmt.Printf("You have updated the document:\n%s\n", string(documentContent))
	}
}
When you run the code, you see a result similar to the following output.
You have updated the document:
{
  "_id": "example",
  "_rev": "2-4e2178e85cffb32d38ba4e451f6ca376",
  "address": "19 Front Street, Darlington, DL5 1TY",
  "name": "Bob Smith"
}

4. Delete your previously created document

Note: This example code assumes that you have created both the orders database and the example document by running the previous example code successfully. Otherwise, the following error message occurs, "Cannot delete document because either 'orders' database or 'example' document was not found."

Delete code example
package main

import (
	"fmt"

	"github.com/IBM/cloudant-go-sdk/cloudantv1"
)

func main() {

	// 1. Create a client with `CLOUDANT` default service name =============
	client, err := cloudantv1.NewCloudantV1UsingExternalConfig(
		&cloudantv1.CloudantV1Options{},
	)
	if err != nil {
		panic(err)
	}

	// 2. Delete the document ==============================================
	exampleDbName := "orders"
	exampleDocID := "example"

	// 2.1. Get the document if it previously existed in the database
	document, getDocumentResponse, err := client.GetDocument(
		client.NewGetDocumentOptions(
			exampleDbName,
			exampleDocID,
		),
	)
	if err != nil {
		if getDocumentResponse.StatusCode == 404 {
			fmt.Printf("Cannot delete document because "+
				"either \"%s\" database or \"%s\" document was not found.\n",
				exampleDbName,
				exampleDocID)
		} else {
			panic(err)
		}
	}
	// 2.2. Use its latest revision to delete
	if document != nil {
		deleteDocumentResult, _, err := client.DeleteDocument(
			client.NewDeleteDocumentOptions(
				exampleDbName,
				*document.ID,
			).SetRev(*document.Rev),
		)
		if err != nil {
			panic(err)
		}

		if *deleteDocumentResult.Ok {
			fmt.Println("You have deleted the document.")
		}
	}
}
When you run the code, you see the following output.
You have deleted the document.

Error handling

For sample code on handling errors, see Cloudant API docs.

Raw IO

For endpoints that read or write document content it is possible to bypass usage of the built-in models and send or receive a bytes response. For examples of using byte streams, see the API reference documentation ("Example request as a stream" section).

Further resources

  • Cloudant API docs: API reference including usage examples for Cloudant Go SDK API.
  • Godoc: Cloudant Go SDK API Documentation.
  • Cloudant docs: The official documentation page for Cloudant.
  • Cloudant blog: Many useful articles about how to optimize Cloudant for common problems.

Questions

If you are having difficulties using this SDK or have a question about the IBM Cloud services, ask a question on Stack Overflow.

Issues

If you encounter an issue with the project, you are welcome to submit a bug report. Before you submit a bug report, search for similar issues and review the KNOWN_ISSUES file to verify that your issue hasn't been reported yet.

Open source at IBM

Find more open source projects on the IBM Github page.

Contributing

For more information, see CONTRIBUTING.

License

This SDK is released under the Apache 2.0 license. To read the full text of the license, see LICENSE.