Dados em tempo real em um front-end do React JavaScript com Change Streams
Joel Lord6 min read • Published Oct 04, 2022 • Updated Sep 09, 2024
Avalie esse Tutorial
Atualmente, em muitos aplicativos, você deseja que os dados sejam exibidos em tempo real. Seja um sensor IoT relatando um valor, um valor de ação que você deseja rastrear ou um aplicativo de bate-papo, você desejará que os dados atualizem automaticamente sua interface do usuário. Isso é possível usando MongoDB Change Streams com o Realm Web SDK.
Neste tutorial, você aprenderá a usar o Realm Web SDK para exibir as alterações em uma coleção à medida que elas ocorrem.
Para seguir este tutorial, você precisará de um cluster do Atlas. A camada grátis será mais que suficiente para as necessidades deste tutorial. Se ainda não tiver um, você pode encontrar instruções sobre como criar um cluster na documentação.
Quando você tiver um cluster, crie um novo banco de dados chamado
data
, com uma coleção changestream
.Você também precisará de um aplicativo do Application Services. As instruções para criar uma nova aplicação também podem ser encontradas na documentação. Siga as instruções para criar um novo aplicativo sem modelo.
Esta aplicação exibirá qualquer operação que seja executada em uma coleção específica. Para fazer isso, precisaremos configurar regras sobre quem tem acesso aos dados (todos) e como os usuários se autenticarão (anonimamente).
Você precisará do ID do aplicativo quando começar a criá-lo. Ao abrir o aplicativo pela primeira vez (ou ao clicar no item da barra de navegação com o nome do seu aplicativo), você verá a página inicial com as informações sobre esse aplicativo. Logo na parte superior, você notará um campo chamado "App ID". Este é o ID do seu aplicativo.
Você pode copiá-lo e colá-lo em algum lugar ou apenas voltar a essa tela mais tarde quando precisar dele.
No menu de navegação esquerdo do Atlas App Services, procure o item "Rules". Isso listará todos os seus bancos de dados e coleções no cluster associado a esse aplicativo. Selecione o banco de dados
data
e a coleção changestream
. Será solicitado que você crie uma nova função para essa coleção.Use a predefinição
readAll
e, em seguida, clique no botão "Add preset role". Isso criará uma nova função que terá acesso completo de leitura aos dados dessa coleção. Se você quiser criar uma função que tenha acesso apenas aos dados de propriedade do usuário, isso poderá ser feito com uma função personalizada aqui.Para este aplicativo, não exigiremos autenticação, o que significa que qualquer visitante deste site terá acesso a todos os dados. No nosso caso, é isso que queremos, mas em um aplicativo de produção, talvez você queira configurar um provedor de autenticação real.
Na barra de navegação à esquerda, clique no item "Autenticação". Na tabela exibida, procure a linha "Permitir que os usuários façam login anonimamente".
Clique no botão "Editar". Na próxima tela, alterne o botão "Provedor habilitado" para ativá-lo. Depois de clicar no botão Salvar, volte para a página dos provedores de autenticação e verifique se ela está ativada.
Por enquanto, é tudo o que você precisa na interface do usuário do Atlas App Services. Procure a barra azul na parte superior da tela.
Clique no botão "Revisar rascunho e implantar" e aceite as alterações.
Seu aplicativo agora está pronto para ser usado.
Começaremos com um aplicativo React em branco gerado com a ferramenta
create-react-app
para este aplicativo.Em seu terminal, execute o seguinte comando.
1 npx create-react-app realm-web-changestreams
Em seguida, instale a biblioteca necessária para usar o Realm Web SDK e inicie o aplicativo.
1 cd realm-web-changestreams 2 npm install realm-web 3 npm start
Isso abrirá uma janela do navegador com o aplicativo em execução. Com seu editor de código favorito, abra o código-fonte desse aplicativo e procure o arquivo App.js.
Você substituirá todo o conteúdo deste arquivo para que possa prosseguir e excluir tudo lá.
Agora, comece com esse código padrão para seu arquivo App.js.
1 import React, {useState, useEffect} from "react" 2 import * as Realm from "realm-web"; 3 4 // Create the Application 5 6 // Define the App component 7 8 const App = () => { 9 // Set state variables 10 11 // This useEffect hook will run only once when the page is loaded 12 13 useEffect(() => { 14 15 }, []); 16 17 // Return the JSX that will generate HTML for the page 18 19 return ( 20 <div className="App"> 21 22 </div> 23 ); 24 }; 25 26 export default App;
No comentário Create the Application, insira o seguinte.
1 // Create the Application 2 3 const app = new Realm.App({ id: "<YOUR_APP_ID>"});
Isso instanciará seu aplicativo Atlas. Não se esqueça de alterar o ID para o identificador do seu aplicativo.
Em seguida, precisaremos de duas variáveis de estado. O primeiro —
user
— conterá o objeto de usuário criado pelo Realm SDK depois de autenticado. O segundo —events
— conterá qualquer novo evento do banco de dados. Esses eventos serão operações (criar, atualizar ou excluir) realizadas no banco de dados, juntamente com o _id
do documento e o documento completo.Adicione o seguinte código após o comentário Set state variables (Definir variáveis de estado ).
1 // Set state variables 2 const [user, setUser] = useState(); 3 const [events, setEvents] = useState([]);
A seguir é a função
useEffect
. Aqui, você criará uma função chamada login
que autenticará anonimamente no aplicativo. Em seguida, ele atualizará o objeto de usuário no estado.1 // This useEffect hook will run only once when the page is loaded 2 3 useEffect(() => { 4 const login = async () => { 5 // Authenticate anonymously 6 const user = await app.logIn(Realm.Credentials.anonymous()); 7 setUser(user); 8 9 // Connect to the database 10 const mongodb = app.currentUser.mongoClient("mongodb-atlas"); 11 const collection = mongodb.db("data").collection("changestream"); 12 13 // Everytime a change happens in the stream, add it to the list of events 14 for await (const change of collection.watch()) { 15 setEvents(events => [...events, change]); 16 } 17 } 18 login(); 19 }, []);
Finalmente, altere o código JSX para renderizar uma tabela com os eventos.
1 // Return the JSX that will generate HTML for the page 2 return ( 3 <div className="App"> 4 {!!user && 5 <div className="App-header"> 6 <h1>Connected as user ${user.id}</h1> 7 <div> 8 <p>Latest events:</p> 9 <table> 10 <thead> 11 <tr><td>Operation</td><td>Document Key</td><td>Full Document</td></tr> 12 </thead> 13 <tbody> 14 {events.map((e, i) => ( 15 <tr key={i}><td>{e.operationType}</td><td>{e.documentKey._id.toString()}</td><td>{JSON.stringify(e.fullDocument)}</td></tr> 16 ))} 17 </tbody> 18 </table> 19 </div> 20 </div> 21 } 22 </div> 23 );
Isso é tudo que você precisa para sua aplicação. Se você olhar para o navegador, verá o aplicativo em execução.
Na interface do usuário do Atlas, crie, edite ou exclua itens da coleção do changestream. Ao realizar essas operações, você verá seu novo aplicativo da web exibindo cada uma dessas operações em tempo real conforme elas acontecem.
Observação: ao executar esse aplicativo, você pode notar que alguns dos eventos são duplicados. Isso se deve à ferramenta React.StrictMode, que faz uma segunda passagem em seu código para notificá-lo de qualquer erro. Isso só acontece em produção e não ocorrerá se você executar
npm run build
.O mesmo aplicativo pode ser reescrito em JavaScript simples com menos de 50 linhas. As principais diferenças com o aplicativo React é que o
realm-web
é carregado por meio de uma tag de script e que o código para criar a tabela não usa JSX.1 <html> 2 <body> 3 <h1>Connected as user $<span id="userId"></span></h1> 4 <div> 5 <p>Latest events:</p> 6 <table> 7 <thead> 8 <tr><td>Operation</td><td>Document Key</td><td>Full Document</td></tr> 9 </thead> 10 <tbody id="tableBody"></tbody> 11 </table> 12 </div> 13 </body> 14 15 <!-- Import the Realm Web SDK --> 16 <script src="https://unpkg.com/realm-web/dist/bundle.iife.js"></script> 17 18 <script> 19 const main = async () => { 20 //Create the application 21 const app = new Realm.App({ id: "application-1-abcde" }); 22 23 // Authenticate anonymously 24 const user = await app.logIn(Realm.Credentials.anonymous()); 25 document.querySelector("#userId").textContent = user.id; 26 27 // Connect to the database 28 const mongodb = app.currentUser.mongoClient("mongodb-atlas"); 29 const collection = mongodb.db("data").collection("changestream"); 30 31 // Everytime a change happens in the stream, add it to the list of events 32 for await (const change of collection.watch()) { 33 let operationCell = document.createElement("td"); 34 operationCell.textContent = change.operationType; 35 let keyCell = document.createElement("td"); 36 keyCell.textContent = change.documentKey._id.toString(); 37 let fullDocumentCell = document.createElement("td"); 38 fullDocumentCell.textContent = JSON.stringify(change.fullDocument); 39 let eventRow = document.createElement("tr"); 40 eventRow.appendChild(operationCell); 41 eventRow.appendChild(keyCell); 42 eventRow.appendChild(fullDocumentCell); 43 let tableBody = document.querySelector("#tableBody"); 44 tableBody.appendChild(eventRow); 45 } 46 } 47 main(); 48 </script> 49 </html>
Os change streams são uma funcionalidade muito poderosa no MongoDB. Eles permitem que você crie aplicativos que exibem e reagem às informações em tempo real sem precisar de um back-end.
Se você quiser um desafio adicional, que tal criar um aplicativo de bate-papo usando Change Streams? Adicione um formulário que usará um endpoint Atlas HTTPS para adicionar entradas ao banco de dados e, em seguida, liste as mensagens de bate-papo ouvindo novas alterações na coleção.