Search code examples
node.jsmongodbrestexpressreal-time

How to use MongoDB change streams with node js via a REST API microservice (built with Express)


I'm using react js for building frontend for a website. An express server (which is a microservice) sits in between the front end and MongoDB. I make Axios calls from react js to express server (URL = http://localhost:5688/chat ) using GET, POST, PUT whenever and wherever needed.

something like below

Client side

var resp = axios.get(`http://localhost:5688/chat`);
resp.then((response) => {
this.setState({data: response.data})
})

Server side

app.js

var app = express();

app.get('/chat', function (req, res) {
    try {
        var MongoClient = require('mongodb').MongoClient;
        var url = '***********';
        MongoClient.connect(url, { useUnifiedTopology: true }, function(err, client) {
             if (err){
                console.log('error occured while connection to databse ' + err);
             }
             else{
                db.collection(collectionName).find({}).toArray(function(err, result){
                    if (err) {throw err;}
                    else{
                        client.close();
                        res.join(result); // the result would contain the data fetch from db and will be returned to my axios call
                    }
                });
            }
        });
    }
    catch (ex) {
        res.json(ex);
    }
});

app.listen(5688, function(){
    console.log('Server listening at http://localhost:5688');
});

Above is how I've implemented a GET call. Similarly, I've implemented POST and PUT methods as well.

PS: I removed a lot of intermediate code which is not very helpful for this question

Now I want to use MongoDB change stream to listen to all changes that happen to my collection on MongoDB. I'm aware of the tutorials that show how we can log the updated documents in the express server.....such as this tutorial. This makes it possible for my express server to get all the updated documents whenever data in my DB is changed.

But what I'm not sure about is how I can pass this new data to my client so that I can update my react component's state with this new data.

How do I make my frontend code sitting in my browser continuously listen to my express server (a REST API) which is already continuously listening to all changes in MongoDB with the help of change streams?

Is socket the only way to make my client continuously listen to my server? if so, how would I pass the new data coming from MongoDB streaming to the socket on the express server

Please let me know if I should provide more details. Thank you so much.


Solution

  • I will give you an example from my own project in production:

    //Server-side
    
    //Assume tweetDB is the DB 
    //Assume you have socket.io setup
    
    //MongoDB Change Stream
    const changeStream = tweetDB.watch();
    
    
    changeStream.on('change', (changes) => {
    
    //Add a event emitter
                socket.compress(true).emit('mongoStream',changes);
    
            });
    
    
    //Client-side in a js file or a script tag
    //Assuming you have established a WebSocket connection already
    
    //Add an event listener to listen for back end changes. 
    
    socket.on('mongoStream',data=>{
    console.log(data)
    
    });
    
    //Note: Socket.io is event-driven.
    
    //Add an event emitter
    socket.emit('eventName','dataToEmit');
    
    //Add an event listener
    socket.on('eventName',data=>{
    
    //Process the data here
    
    });