Condividi tramite


Creare un'app console Go con Azure Cosmos DB per MongoDB vCore

Questa guida illustra come creare un'applicazione console Go per connettersi a un cluster vCore di Azure Cosmos DB per MongoDB. È possibile configurare l'ambiente di sviluppo, usare il azidentity pacchetto di Azure SDK for Go per l'autenticazione ed eseguire operazioni comuni sui documenti nel database.

Prerequisiti

  • Un cluster esistente di Azure Cosmos DB per MongoDB (vCore).
  • Autenticazione di Microsoft Entra configurata per il cluster con il ruolo dbOwner assegnato alla tua identità.

  • Versione più recente di Go.

Configurare l'applicazione console

Creare quindi un nuovo progetto di applicazione console e importare le librerie necessarie per l'autenticazione nel cluster.

  1. Creare un nuovo modulo Go per il progetto usando il go mod init comando .

    go mod init cosmicworks
    
  2. Installare il azidentity pacchetto per gestire l'autenticazione con Microsoft Entra ID.

    go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
    
  3. Installare il pacchetto mongo per interagire con il cluster vCore di MongoDB.

    go get -u  go.mongodb.org/mongo-driver/v2/mongo
    
  4. Creare un nuovo file denominato main.go nella directory del progetto.

    touch main.go
    

Connettersi al cluster

Ora, utilizza la libreria Azure.Identity per ottenere un TokenCredential da utilizzare per connetterti al cluster. Il driver Ufficiale di MongoDB ha un'interfaccia speciale che deve essere implementata per ottenere i token da Microsoft Entra per l'uso durante la connessione al cluster.

  1. Per iniziare, importare i pacchetti necessari nella parte superiore del 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"
    )
    
  2. Creare un contesto in background usato in tutta l'applicazione.

     ctx := context.Background()
    
  3. Creare un'istanza di DefaultAzureCredential usata per eseguire l'autenticazione con Microsoft Entra ID.

     credential, err := azidentity.NewDefaultAzureCredential(nil)
     if err != nil {
     	panic(err)
     }
    
  4. Creare una funzione di callback che ottiene i token di accesso quando il driver MongoDB deve eseguire l'autenticazione.

     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
     }
    
  5. Impostare il nome del cluster e costruire l'URI di connessione.

     clusterName := "<azure-cosmos-db-mongodb-vcore-cluster-name>"
     uri := fmt.Sprintf("mongodb+srv://%s.global.mongocluster.cosmos.azure.com/", clusterName)
    
  6. Configurare le credenziali di autenticazione per il client MongoDB.

     auth := options.Credential{
     	AuthMechanism:       "MONGODB-OIDC",
     	OIDCMachineCallback: azureIdentityTokenCallback,
     }
    
  7. Configurare le opzioni client con parametri di connessione, configurazione TLS (Transport Layer Security) e autenticazione.

     clientOptions := options.Client().
     	ApplyURI(uri).
     	SetConnectTimeout(2 * time.Minute).
     	SetRetryWrites(true).
     	SetTLSConfig(&tls.Config{}).
     	SetAuth(auth)
    
  8. Creare un'istanza del client MongoDB usando le opzioni configurate.

     client, err := mongo.Connect(clientOptions)
     if err != nil {
     	panic(err)
     }
    
     fmt.Println("Client created")
    
  9. Aggiungere un'istruzione defer per assicurarsi che il client sia disconnesso correttamente quando l'applicazione termina.

     defer func() {
     	if err = client.Disconnect(ctx); err != nil {
     		panic(err)
     	}
     }()
    

Eseguire operazioni comuni

Infine, usare la libreria ufficiale per eseguire attività comuni con database, raccolte e documenti. In questo caso si usano le stesse classi e metodi usati per interagire con MongoDB o DocumentDB per gestire le raccolte e gli elementi.

  1. Ottieni un riferimento al tuo database per nome.

     database := client.Database("<database-name>")
    
     fmt.Println("Database pointer created")
    
  2. Ottenere un riferimento alla raccolta all'interno del database.

     collection := database.Collection("<collection-name>")
    
     fmt.Println("Collection pointer created")
    
  3. Definire una struttura di tipo Product per rappresentare la struttura del documento.

    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"`
    }
    
  4. Creare o aggiornare un documento usando l'operazione collection.ReplaceOne configurata per 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)
    
  5. Leggere un documento specifico usando collection.FindOne e un filtro con _id e category.

     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)
    
  6. Eseguire una query per più documenti corrispondenti a uno specifico category usando collection.Find.

     queryFilter := bson.D{{Key: "category", Value: "gear-surf-surfboards"}}
     cursor, err := collection.Find(ctx, queryFilter)
     if err != nil {
     	panic(err)
     }
    
  7. Recuperare tutti i documenti corrispondenti dal cursore.

     var products []Product
     if err = cursor.All(ctx, &products); err != nil {
     	panic(err)
     }
    
  8. Scorrere e visualizzare tutti i prodotti trovati nella query.

     for _, product := range products {
     	json, err := json.Marshal(product)
     	if err != nil {
     		panic(err)
     	}
     	fmt.Printf("Found document:\t%s\n", string(json))
     }