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.
- If you don't have an Azure subscription, create an account for free.
- If you have an existing Azure subscription, create a new 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 logincommand.
- 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
rootrole.- 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 initcommand.go mod init cosmicworksInstall the
azidentitypackage to handle authentication with Microsoft Entra ID.go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentityInstall the
mongopackage interact with your MongoDB vCore cluster.go get -u go.mongodb.org/mongo-driver/v2/mongoCreate a new file named
main.goin 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.gofile.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
DefaultAzureCredentialthat 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.ReplaceOneoperation 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.FindOneand a filter with_idandcategory.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
categoryusingcollection.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)) }