Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This guide explains how to build a Go console application to connect to an Azure Cosmos DB for MongoDB vCore cluster. You set up your development environment, use the azidentity
package from the Azure SDK for Go to authenticate, and perform common operations on documents in the database.
Prerequisites
- An existing Azure Cosmos DB for MongoDB (vCore) cluster.
The latest version of the Azure CLI in Azure Cloud Shell.
- If you prefer to run CLI reference commands locally, sign in to the Azure CLI by using the
az login
command.
- If you prefer to run CLI reference commands locally, sign in to the Azure CLI by using the
Microsoft Entra authentication configured for the cluster with your identity granted
dbOwner
role.- To enable Microsoft Entra authentication, review the configuration guide.
Latest version of Go.
Configure your console application
Next, create a new console application project and import the necessary libraries to authenticate to your cluster.
Create a new Go module for your project using the
go mod init
command.go mod init cosmicworks
Install the
azidentity
package to handle authentication with Microsoft Entra ID.go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
Install the
mongo
package interact with your MongoDB vCore cluster.go get -u go.mongodb.org/mongo-driver/v2/mongo
Create a new file named
main.go
in your project directory.touch main.go
Connect to the cluster
Now, use the Azure.Identity
library to get a TokenCredential
to use to connect to your cluster. The official MongoDB driver has a special interface that must be implemented to obtain tokens from Microsoft Entra for use when connecting to the cluster.
Start by importing the required packages at the top of your
main.go
file.import ( "context" "crypto/tls" "encoding/json" "fmt" "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" )
Create a background context that is used throughout your application.
ctx := context.Background()
Create an instance of
DefaultAzureCredential
that is used to authenticate with Microsoft Entra ID.credential, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { panic(err) }
Create a callback function that obtains access tokens when the MongoDB driver needs to authenticate.
azureIdentityTokenCallback := func(_ context.Context, _ *options.OIDCArgs) (*options.OIDCCredential, error) { accessToken, err := credential.GetToken(ctx, policy.TokenRequestOptions{ Scopes: []string{"https://ossrdbms-aad.database.windows.net/.default"}, }) if err != nil { return nil, err } return &options.OIDCCredential{ AccessToken: accessToken.Token, }, nil }
Set your cluster name and construct the connection URI.
clusterName := "<azure-cosmos-db-mongodb-vcore-cluster-name>" uri := fmt.Sprintf("mongodb+srv://%s.global.mongocluster.cosmos.azure.com/", clusterName)
Configure the authentication credentials for the MongoDB client.
auth := options.Credential{ AuthMechanism: "MONGODB-OIDC", OIDCMachineCallback: azureIdentityTokenCallback, }
Set up the client options with connection parameters, transport layer security (TLS) configuration, and authentication.
clientOptions := options.Client(). ApplyURI(uri). SetConnectTimeout(2 * time.Minute). SetRetryWrites(true). SetTLSConfig(&tls.Config{}). SetAuth(auth)
Create a MongoDB client instance using the configured options.
client, err := mongo.Connect(clientOptions) if err != nil { panic(err) } fmt.Println("Client created")
Add a defer statement to ensure the client is properly disconnected when your application exits.
defer func() { if err = client.Disconnect(ctx); err != nil { panic(err) } }()
Perform common operations
Finally, use the official library to perform common tasks with databases, collections, and documents. Here, you use the same classes and methods you would use to interact with MongoDB or DocumentDB to manage your collections and items.
Get a reference to your database by name.
database := client.Database("<database-name>") fmt.Println("Database pointer created")
Get a reference to your collection within the database.
collection := database.Collection("<collection-name>") fmt.Println("Collection pointer created")
Define a Product struct to represent your document structure.
type Product struct { ID string `bson:"_id"` Category string `bson:"category"` Name string `bson:"name"` Quantity int `bson:"quantity"` Price decimal128.Decimal128 `bson:"price"` Clearance bool `bson:"clearance"` }
Create or update a document using the
collection.ReplaceOne
operation configured for upsert.opts := options.Replace().SetUpsert(true) upsertFilter := bson.D{{Key: "_id", Value: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb"}} priceDecimal, err := bson.ParseDecimal128("850.00") if err != nil { panic(err) } document := Product{ ID: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb", Category: "gear-surf-surfboards", Name: "Yamba Surfboard", Quantity: 12, Price: priceDecimal, Clearance: false} result, err := collection.ReplaceOne(ctx, upsertFilter, document, opts) if err != nil { panic(err) } fmt.Printf("Documents upserted count:\t%d\n", result.UpsertedCount)
Read a specific document using
collection.FindOne
and a filter with_id
andcategory
.readFilter := bson.D{{Key: "_id", Value: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb"}, {Key: "category", Value: "gear-surf-surfboards"}} var target Product err = collection.FindOne(ctx, readFilter).Decode(&target) if err != nil { panic(err) } fmt.Printf("Read document name:\t%s\n", target.Name)
Query for multiple documents matching a specific
category
usingcollection.Find
.queryFilter := bson.D{{Key: "category", Value: "gear-surf-surfboards"}} cursor, err := collection.Find(ctx, queryFilter) if err != nil { panic(err) }
Retrieve all matching documents from the cursor.
var products []Product if err = cursor.All(ctx, &products); err != nil { panic(err) }
Iterate through and display all the products found in the query.
for _, product := range products { json, err := json.Marshal(product) if err != nil { panic(err) } fmt.Printf("Found document:\t%s\n", string(json)) }