Quickstart: Connect a Go application to Azure Cosmos DB for MongoDB
APPLIES TO: MongoDB
Azure Cosmos DB is a multi-model database service that lets you quickly create and query document, table, key-value, and graph databases with multiple-regional distribution and horizontal scale capabilities. In this quickstart, you create and manage an Azure Cosmos DB account by using the Azure CLI, clone an existing sample application from GitHub and configure it to work with Azure Cosmos DB.
The sample application is a command-line based todo
management tool written in Go. Azure Cosmos DB's API for MongoDB is compatible with the MongoDB wire protocol, making it possible for any MongoDB client driver to connect to it. This application uses the Go driver for MongoDB in a way that is transparent to the application that the data is stored in an Azure Cosmos DB database.
Prerequisites
- An Azure account with an active subscription. Create one. Or try Azure Cosmos DB for free without an Azure subscription. You can also use the Azure Cosmos DB Emulator with the connection string
.mongodb://localhost:C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==@localhost:10255/admin?ssl=true
. - Go installed on your computer, and a working knowledge of Go.
- Git.
You can use the local Azure CLI.
If you prefer, install the Azure CLI to run CLI reference commands.
Local Azure CLI, see how to install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
Sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign in with the Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
Clone the sample application
Run the following commands to clone the sample repository.
Open a command prompt, create a new folder named
git-samples
, then close the command prompt.mkdir "C:\git-samples"
Open a git terminal window, such as git bash, and use the
cd
command to change to the new folder to install the sample app.cd "C:\git-samples"
Run the following command to clone the sample repository. This command creates a copy of the sample app on your computer.
git clone https://github.com/Azure-Samples/cosmosdb-go-mongodb-quickstart
Review the code
This step is optional. If you're interested in learning how the application works, you can review the following snippets. Otherwise, you can skip ahead to Run the application. The application layout is as follows:
.
├── go.mod
├── go.sum
└── todo.go
The following snippets are all taken from the todo.go
file.
Connecting the Go app to Azure Cosmos DB
clientOptions
encapsulates the connection string for Azure Cosmos DB, which is passed in using an environment variable (details in the upcoming section). The connection is initialized using mongo.NewClient
to which the clientOptions
instance is passed. Ping
function is invoked to confirm successful connectivity (it'is a fail-fast strategy).
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
clientOptions := options.Client().ApplyURI(mongoDBConnectionString).SetDirect(true)
c, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatalf("unable to initialize connection %v", err)
}
err = c.Ping(ctx, nil)
if err != nil {
log.Fatalf("unable to connect %v", err)
}
Note
Using the SetDirect(true)
configuration is important, without which you will get the following connectivity error: unable to connect connection(cdb-ms-prod-<azure-region>-cm1.documents.azure.cn:10255[-4]) connection is closed
Create a todo
item
To create a todo
, we get a handle to a mongo.Collection
and invoke the InsertOne
function.
func create(desc string) {
c := connect()
ctx := context.Background()
defer c.Disconnect(ctx)
todoCollection := c.Database(database).Collection(collection)
r, err := todoCollection.InsertOne(ctx, Todo{Description: desc, Status: statusPending})
if err != nil {
log.Fatalf("failed to add todo %v", err)
}
We pass in a Todo
struct that contains the description and the status (which is initially set to pending
):
type Todo struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
Description string `bson:"description"`
Status string `bson:"status"`
}
List todo
items
We can list TODOs based on criteria. A bson.D
is created to encapsulate the filter criteria:
func list(status string) {
.....
var filter interface{}
switch status {
case listAllCriteria:
filter = bson.D{}
case statusCompleted:
filter = bson.D{{statusAttribute, statusCompleted}}
case statusPending:
filter = bson.D{{statusAttribute, statusPending}}
default:
log.Fatal("invalid criteria for listing todo(s)")
}
Find
is used to search for documents based on the filter and the result is converted into a slice of Todo
todoCollection := c.Database(database).Collection(collection)
rs, err := todoCollection.Find(ctx, filter)
if err != nil {
log.Fatalf("failed to list todo(s) %v", err)
}
var todos []Todo
err = rs.All(ctx, &todos)
if err != nil {
log.Fatalf("failed to list todo(s) %v", err)
}
Finally, the information is rendered in tabular format:
todoTable := [][]string{}
for _, todo := range todos {
s, _ := todo.ID.MarshalJSON()
todoTable = append(todoTable, []string{string(s), todo.Description, todo.Status})
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"ID", "Description", "Status"})
for _, v := range todoTable {
table.Append(v)
}
table.Render()
Update a todo
item
A todo
can be updated based on its _id
. A bson.D
filter is created based on the _id
and another one is created for the updated information, which is a new status (completed
or pending
) in this case. Finally, the UpdateOne
function is invoked with the filter and the updated document:
func update(todoid, newStatus string) {
....
todoCollection := c.Database(database).Collection(collection)
oid, err := primitive.ObjectIDFromHex(todoid)
if err != nil {
log.Fatalf("failed to update todo %v", err)
}
filter := bson.D{{"_id", oid}}
update := bson.D{{"$set", bson.D{{statusAttribute, newStatus}}}}
_, err = todoCollection.UpdateOne(ctx, filter, update)
if err != nil {
log.Fatalf("failed to update todo %v", err)
}
Delete a todo
A todo
is deleted based on its _id
and it'is encapsulated in the form of a bson.D
instance. DeleteOne
is invoked to delete the document.
func delete(todoid string) {
....
todoCollection := c.Database(database).Collection(collection)
oid, err := primitive.ObjectIDFromHex(todoid)
if err != nil {
log.Fatalf("invalid todo ID %v", err)
}
filter := bson.D{{"_id", oid}}
_, err = todoCollection.DeleteOne(ctx, filter)
if err != nil {
log.Fatalf("failed to delete todo %v", err)
}
}
Build the application
Change into the directory where you cloned the application and build it (using go build
).
cd monogdb-go-quickstart
go build -o todo
To confirm that the application was built properly.
./todo --help
Setup Azure Cosmos DB
Sign in to Azure
If you choose to install and use the CLI locally, this topic requires that you're running the Azure CLI version 2.0 or later. Run az --version
to find the version. If you need to install or upgrade, see [Install Azure CLI].
If you're using an installed Azure CLI, sign in to your Azure subscription with the az login command and follow the on-screen directions. You can skip this step if you're using the Azure Cloud Shell.
az login
Add the Azure Cosmos DB module
If you are using an installed Azure CLI, check to see if the cosmosdb
component is already installed by running the az
command. If cosmosdb
is in the list of base commands, proceed to the next command.
If cosmosdb
isn't in the list of base commands, reinstall Azure CLI.
Create a resource group
Create a resource group with the az group create. An Azure resource group is a logical container into which Azure resources like web apps, databases, and storage accounts are deployed and managed.
The following example creates a resource group in the China North region. Choose a unique name for the resource group.
Copy the following command into your local CLI command prompt.
az group create --name myResourceGroup --location "China North"
Create an Azure Cosmos DB account
Create an Azure Cosmos DB account with the az cosmosdb create command.
In the following command, please substitute your own unique Azure Cosmos DB account name where you see the <cosmosdb-name>
placeholder. This unique name will be used as part of your Azure Cosmos DB endpoint (https://<cosmosdb-name>.documents.azure.cn/
), so the name needs to be unique across all Azure Cosmos DB accounts in Azure.
az cosmosdb create --name <cosmosdb-name> --resource-group myResourceGroup --kind MongoDB
The --kind MongoDB
parameter enables MongoDB client connections.
When the Azure Cosmos DB account is created, the Azure CLI shows information similar to the following example.
Note
This example uses JSON as the Azure CLI output format, which is the default. To use another output format, see Output formats for Azure CLI commands.
{
"databaseAccountOfferType": "Standard",
"documentEndpoint": "https://<cosmosdb-name>.documents.azure.cn:443/",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Document
DB/databaseAccounts/<cosmosdb-name>",
"kind": "MongoDB",
"location": "China North",
"name": "<cosmosdb-name>",
"readLocations": [
{
"documentEndpoint": "https://<cosmosdb-name>-chinanorth.documents.azure.cn:443/",
"failoverPriority": 0,
"id": "<cosmosdb-name>-chinanorth",
"locationName": "China North",
"provisioningState": "Succeeded"
}
],
"resourceGroup": "myResourceGroup",
"type": "Microsoft.DocumentDB/databaseAccounts",
"writeLocations": [
{
"documentEndpoint": "https://<cosmosdb-name>-chinanorth.documents.azure.cn:443/",
"failoverPriority": 0,
"id": "<cosmosdb-name>-chinanorth",
"locationName": "China North",
"provisioningState": "Succeeded"
}
]
}
Retrieve the database key
In order to connect to an Azure Cosmos DB database, you need the database key. Use the az cosmosdb keys list command to retrieve the primary key.
az cosmosdb keys list --name <cosmosdb-name> --resource-group myResourceGroup --query "primaryMasterKey"
The Azure CLI outputs information similar to the following example.
"RUayjYjixJDWG5xTqIiXjC..."
Configure the application
Export the connection string, MongoDB database, and collection names as environment variables.
export MONGODB_CONNECTION_STRING="mongodb://<COSMOSDB_ACCOUNT_NAME>:<COSMOSDB_PASSWORD>@<COSMOSDB_ACCOUNT_NAME>.documents.azure.cn:10255/?ssl=true&replicaSet=globaldb&maxIdleTimeMS=120000&appName=@<COSMOSDB_ACCOUNT_NAME>@"
Note
The ssl=true
option is important because of Azure Cosmos DB requirements. For more information, see Connection string requirements.
For the MONGODB_CONNECTION_STRING
environment variable, replace the placeholders for <COSMOSDB_ACCOUNT_NAME>
and <COSMOSDB_PASSWORD>
<COSMOSDB_ACCOUNT_NAME>
: The name of the Azure Cosmos DB account you created<COSMOSDB_PASSWORD>
: The database key extracted in the previous step
export MONGODB_DATABASE=todo-db
export MONGODB_COLLECTION=todos
You can choose your preferred values for MONGODB_DATABASE
and MONGODB_COLLECTION
or leave them as is.
Run the application
To create a todo
./todo --create "Create an Azure Cosmos DB database account"
If successful, you should see an output with the MongoDB _id
of the newly created document:
added todo ObjectID("5e9fd6befd2f076d1f03bd8a")
Create another todo
./todo --create "Get the MongoDB connection string using the Azure CLI"
List all the todo
s
./todo --list all
You should see the ones you just added in a tabular format as such:
+----------------------------+--------------------------------+-----------+
| ID | DESCRIPTION | STATUS |
+----------------------------+--------------------------------+-----------+
| "5e9fd6b1bcd2fa6bd267d4c4" | Create an Azure Cosmos DB | pending |
| | database account | |
| "5e9fd6befd2f076d1f03bd8a" | Get the MongoDB connection | pending |
| | string using the Azure CLI | |
+----------------------------+--------------------------------+-----------+
To update the status of a todo
(e.g. change it to completed
status), use the todo
ID:
./todo --update 5e9fd6b1bcd2fa6bd267d4c4,completed
List only the completed todo
s
./todo --list completed
You should see the one you just updated:
+----------------------------+--------------------------------+-----------+
| ID | DESCRIPTION | STATUS |
+----------------------------+--------------------------------+-----------+
| "5e9fd6b1bcd2fa6bd267d4c4" | Create an Azure Cosmos DB | completed |
| | database account | |
+----------------------------+--------------------------------+-----------+
View data in Data Explorer
Data stored in Azure Cosmos DB is available to view and query in the Azure portal.
To view, query, and work with the user data created in the previous step, login to the Azure portal in your web browser.
In the top Search box, enter Azure Cosmos DB. When your Azure Cosmos DB account blade opens, select your Azure Cosmos DB account. In the left navigation, select Data Explorer. Expand your collection in the Collections pane, and then you can view the documents in the collection, query the data, and even create and run stored procedures, triggers, and UDFs.
Delete a todo
using its ID:
./todo --delete 5e9fd6b1bcd2fa6bd267d4c4,completed
List the todo
s to confirm:
./todo --list all
The todo
you just deleted shouldn't be present:
+----------------------------+--------------------------------+-----------+
| ID | DESCRIPTION | STATUS |
+----------------------------+--------------------------------+-----------+
| "5e9fd6befd2f076d1f03bd8a" | Get the MongoDB connection | pending |
| | string using the Azure CLI | |
+----------------------------+--------------------------------+-----------+
Clean up resources
When you're done with your app and Azure Cosmos DB account, you can delete the Azure resources you created so you don't incur more charges. To delete the resources:
In the Azure portal Search bar, search for and select Resource groups.
From the list, select the resource group you created for this quickstart.
On the resource group Overview page, select Delete resource group.
In the next window, enter the name of the resource group to delete, and then select Delete.
Next steps
In this quickstart, you learned how to create an Azure Cosmos DB for MongoDB account using the Azure CLI, and create and run a Go command-line app to manage todo
s. You can now import additional data to your Azure Cosmos DB account.
Trying to do capacity planning for a migration to Azure Cosmos DB? You can use information about your existing database cluster for capacity planning.
- If all you know is the number of vcores and servers in your existing database cluster, read about estimating request units using vCores or vCPUs
- If you know typical request rates for your current database workload, read about estimating request units using Azure Cosmos DB capacity planner