Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Idiomaschevron-right
Gochevron-right

Servidores HTTP persistindo dados no MongoDB

Jorge D. Ortiz-Fuentes5 min read • Published Sep 04, 2024 • Updated Sep 04, 2024
Go
APLICATIVO COMPLETO
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
No artigo anterior e no vídeo correspondente, escrevemos um servidor HTTP básico do zero. Usamos Go 1.22 para lidar com diferentes verbos HTTP e desserializamos dados que foram enviados de um cliente HTTP.
A troca de dados é inútil se você esquecê-los imediatamente. Vamos persistir esses dados usando o MongoDB. Você precisará de um cluster do MongoDB Atlas. O gratuito é mais do que suficiente. Se você não tiver uma conta, poderá encontrar orientações sobre como isso é feito neste workshop ou noYouTube. Você não precisa fazer o laboratório inteiro, apenas as partes "Criar uma conta" e "Criar um cluster" na seção "MongoDB Atlas". Chame seu cluster de "NoteKeeper" em um clusterGRATUITO. Crie um nome de usuário e senha que você usará em um momento. Verifique se o seu endereço IP está incluído. Verifique se o endereço IP do seu servidor tem permissão de acesso. Se você usar o codespace, inclua o endereço 0.0.0.0 para indicar que o acesso é permitido a qualquer IP.

Conecte-se ao MongoDB Atlas a partir do Go

  1. Até agora, usamos pacotes da biblioteca padrão, mas queremos usar o driver do MongoDB para nos conectar ao Atlas cluster. Isso adiciona o driver MongoDB Go às dependências de nosso projeto, incluindo entradas em go.mod para ele e todas as suas dependências. Ele também mantém os hashes das dependências no go.sum para garantir a integridade e baixa todo o código para poder incluí-lo no programa.
    1go get go.mongodb.org/mongo-driver/mongo
  2. O MongoDB usa BSON para serializar e armazenar os dados. Ele é mais eficiente e oferece suporte a mais tipos do que o JSON (estamos olhando para vocês, datas, mas também BinData). E podemos usar a mesma técnica que usamos para desserializar JSON para converter para BSON, mas, nesse caso, a conversão será feita pelo driver. Vamos declarar uma variável global para manter a conexão com o MongoDB Atlas e usá-la nos manipuladores. Essa nãoé uma prática recomendada. Em vez disso, poderíamos definir um tipo que mantenha o cliente e quaisquer outras dependências e forneça métodos - que terão acesso às dependências - que possam ser usados como manipuladores de HTTP.
    1var mdbClient *mongo.Client
  3. Se o seu editor tiver algum problema ao importar os pacotes do driver do MongoDB, você precisará ter esses dois em seu bloco de importação.
    1"go.mongodb.org/mongo-driver/mongo"
    2"go.mongodb.org/mongo-driver/mongo/options"
  4. Na função main, inicializamos a conexão com o Atlas. Observe que esta função retorna duas coisas. Para o primeiro, estamos usando uma variável que já foi definida no escopo global. O segundo, err, não está definido no escopo atual, portanto, poderíamos usar a declaração de variável curta aqui. No entanto, se fizermos isso, ele ignorará a variável global que criamos para o cliente (mdbClient) e definirá uma local somente para esse escopo. Então, vamos usar uma atribuição regular e precisamos que err seja declarada para podermos atribuir um valor a ela.
    1var err error
    2mdbClient, err = mongo.Connect(ARG1, ARG2)
  5. O primeiro argumento dessa chamadaConnect()é um contexto que permite o compartilhamento de dados e solicitações de cancelamento entre a função principal e o cliente. Vamos criar um contexto destinado a fazer trabalho em segundo plano. Você poderia adicionar um cronômetro de cancelamento a esse contexto, entre outras coisas.
    1ctxBg := context.Background()
  6. O segundo argumento é uma estrutura que contém as opções usadas para criar a conexão. O mínimo é ter um URI para o nosso cluster Atlas MongoDB. Obtemos esse URI na página do cluster clicando em "Obter connection string". Criamos uma constante com essa connection string. Não use este. Não vai funcionar. Obtenha-o do seu cluster. Ter o URI de conexão com o usuário e a senha como constante também não é uma prática recomendada. Você deve passar esses dados usando uma variável de ambiente.
    1const connStr string = "mongodb+srv://yourusername:yourpassword@notekeeper.xxxxxx.mongodb.net/?retryWrites=true&w=majority&appName=NoteKeeper"
  7. Agora podemos usar essa constante para criar o segundo argumento em vigor.
    1var err error
    2mdbClient, err = mongo.Connect(ctxBg, options.Client().ApplyURI(connStr))
  8. Se não conseguirmos nos conectar ao Atlas, não adianta continuar, então registramos o erro e saímos. log.Fatal() lida com ambas as coisas.
    1if err != nil {
    2 log.Fatal(err)
    3}
  9. Se a conexão foi bem-sucedida, a primeira coisa que queremos fazer é garantir que ela será fechada se sairmos dessa função. Usamos defer para isso. Tudo o que adiarmos será executado quando sairmos do escopo da função, mesmo que as coisas não corram bem e ocorra um pânico. Incluímos o trabalho em uma função anônima e a chamamos porque defer é uma instrução. Dessa forma, podemos usar o valor de retorno do métodoDisconnect()e agir de acordo.
    1defer func() {
    2 if err = mdbClient.Disconnect(ctxBg); err != nil {
    3 panic(err)
    4 }
    5}()

Persistir dados no MongoDB Atlas do Go

Persistência
  1. Em seguida, queremos utilizar a collection (mais ou menos equivalente a uma tabela em um relational database) que conterá nossas anotações no banco de dadosNoteKeeper. A primeira vez que nos referimos a esta collection, ela é criada. E isso pode ser feito porque não há necessidade de definir o esquema dessa collection antes de adicionar dados a ela. Vamos acessar a collection de dentro do HTTP implementado no CreateNote() pouco antes de escrevermos no gravador de resposta do código anterior.
    1notesCollection := mdbClient.Database("NoteKeeper").Collection("Notes")
  2. Na próxima linha, inserimos a nota obtida desserializando os dados na solicitação. Também a partir da solicitação HTTP, obtemos o contexto que foi usado com ele, para estender seu uso à solicitação do Atlas.
    1result, err := notesCollection.InsertOne(r.Context(), note)
  3. Caso haja algum problema com a solicitaçãoInsertOne(), o manipulador terá que retornar um erro e o status HTTP adequado. Isso deve ser feito antes que qualquer coisa seja gravada no escritor da resposta ou será ignorada. Não é uma prática recomendada retornar o erro do banco de dados ao usuário. Você pode estar revelando muitas informações.
    1if err != nil {
    2 http.Error(w, err.Error(), http.StatusInternalServerError)
    3 return
    4}
  4. E, se tudo correr bem, imprimimos o ID da nova entrada, na parte inferior do manipulador HTTP.
    1log.Printf("Id: %v", result.InsertedID)
  5. Compile e execute. Em seguida, usamos a mesma solicitação que tínhamos antes, só que, dessa vez, os dados também serão persistidos no banco de dados na nuvem.
    1curl -iX POST -d '{ "title": "Master plan", "tags": ["ai","users"], "text": "ubiquitous AI", "scope": {"project": "world domination", "area":"strategy"} }' localhost:8081/notes

Conclusão

Neste artigo, abordamos:
  • O uso de pacotes para incorporar facilmente funcionalidades adicionais (como o driver do MongoDB).
  • A implementação do tratamento de erros em um manipulador HTTP.
  • A persistência de dados moderadamente complexos em um serviço de cloud.
Essas ideias podem ser estendidas para implementar uma REST API com recursos completos, um servidor de back-end ou um microsserviço, então você pode considerar este seu primeiro passo para superpotências Go reais.
No próximo artigo desta série, prestaremos atenção a um detalhe complicado: a simultaneidade. Usaremos goroutines e canais para implementar um desligamento normal de nosso servidor. O repositório contém todo o código desta série e das próximas para que você possa acompanhar.
Mantenha-se atento. Hackeie seu código. Até a próxima!
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.
Iniciar a conversa

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Início rápido

Reagindo às mudanças do banco de dados com o MongoDB Change Streams e Go


Feb 03, 2023 | 5 min read
Tutorial

Entre em alta: usando Docker + Go com MongoDB


Feb 27, 2023 | 9 min read
Início rápido

Transações ACID multidocumento no MongoDB com Go


Apr 03, 2024 | 6 min read
Tutorial

Interagir com o MongoDB em uma função Amazon Web Services Lambda usando o Go


Aug 29, 2024 | 6 min read
Sumário