Partilhar via


Constrói uma aplicação de consola Go com o Azure DocumentDB

Este guia explica como construir uma aplicação de consola Go para se ligar a um cluster Azure DocumentDB. Você configura seu ambiente de desenvolvimento, usa o azidentity pacote do SDK do Azure para Go para autenticar e executar operações comuns em documentos no banco de dados.

Pré-requisitos

  • Uma assinatura do Azure

    • Se você não tiver uma assinatura do Azure, crie uma conta gratuita
  • Um cluster do Azure DocumentDB existente

  • Autenticação do Microsoft Entra configurada para o cluster com o papel atribuído à sua identidade root.

  • Última versão do Go.

Configurar seu aplicativo de console

Em seguida, crie um novo projeto de aplicativo de console e importe as bibliotecas necessárias para autenticar no cluster.

  1. Crie um novo módulo Go para o seu projeto usando o go mod init comando.

    go mod init cosmicworks
    
  2. Instale o azidentity pacote para lidar com a autenticação com o Microsoft Entra ID.

    go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
    
  3. Instale o mongo pacote e interaja com o seu cluster.

    go get -u  go.mongodb.org/mongo-driver/v2/mongo
    
  4. Crie um novo arquivo nomeado main.go no diretório do projeto.

    touch main.go
    

Ligar ao cluster

Agora, use a Azure.Identity biblioteca para obter um TokenCredential para usar para se conectar ao seu cluster. O driver oficial do MongoDB tem uma interface especial que deve ser implementada para obter tokens do Microsoft Entra para uso ao se conectar ao cluster.

  1. Comece importando os pacotes necessários na parte superior do arquivo main.go .

    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. Crie um contexto em segundo plano que seja usado em todo o seu aplicativo.

     ctx := context.Background()
    
  3. Crie uma instância DefaultAzureCredential que seja usada para autenticar com o Microsoft Entra ID.

     credential, err := azidentity.NewDefaultAzureCredential(nil)
     if err != nil {
     	panic(err)
     }
    
  4. Crie uma função de retorno de chamada que obtenha tokens de acesso quando o driver MongoDB precisar se autenticar.

     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. Defina o nome do cluster e construa o URI de conexão.

     clusterName := "<azure-documentdb-cluster-name>"
     uri := fmt.Sprintf("mongodb+srv://%s.global.mongocluster.cosmos.azure.com/", clusterName)
    
  6. Configure as credenciais de autenticação para o cliente MongoDB.

     auth := options.Credential{
     	AuthMechanism:       "MONGODB-OIDC",
     	OIDCMachineCallback: azureIdentityTokenCallback,
     }
    
  7. Configure as opções do cliente com parâmetros de conexão, configuração de segurança da camada de transporte (TLS) e autenticação.

     clientOptions := options.Client().
     	ApplyURI(uri).
     	SetConnectTimeout(2 * time.Minute).
     	SetRetryWrites(true).
     	SetTLSConfig(&tls.Config{}).
     	SetAuth(auth)
    
  8. Crie uma instância de cliente MongoDB usando as opções configuradas.

     client, err := mongo.Connect(clientOptions)
     if err != nil {
     	panic(err)
     }
    
     fmt.Println("Client created")
    
  9. Adicione uma instrução defer para garantir que o cliente seja desconectado corretamente quando o aplicativo for encerrado.

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

Executar operações comuns

Finalmente, use a biblioteca oficial para executar tarefas comuns com bancos de dados, coleções e documentos. Aqui, você usa as mesmas classes e métodos que usaria para interagir com o MongoDB ou o Banco de Dados de Documentos para gerenciar suas coleções e itens.

  1. Obtenha uma referência ao seu banco de dados através do nome.

     database := client.Database("<database-name>")
    
     fmt.Println("Database pointer created")
    
  2. Obtenha uma referência à sua coleção no banco de dados.

     collection := database.Collection("<collection-name>")
    
     fmt.Println("Collection pointer created")
    
  3. Defina uma estrutura de produto para representar a estrutura do 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. Crie ou atualize um documento usando a operação configurada collection.ReplaceOne para 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. Leia um documento específico usando collection.FindOne e um filtro com _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. Consulta por vários documentos que correspondem a um determinado 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. Recupere todos os documentos correspondentes do cursor.

     var products []Product
     if err = cursor.All(ctx, &products); err != nil {
     	panic(err)
     }
    
  8. Percorra e exiba todos os produtos encontrados na consulta.

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