如何通过 REST API 微服务(使用 Express 构建)将 MongoDB 更改流与节点 js 一起使用

Posted

技术标签:

【中文标题】如何通过 REST API 微服务(使用 Express 构建)将 MongoDB 更改流与节点 js 一起使用【英文标题】:How to use MongoDB change streams with node js via a REST API microservice (built with Express) 【发布时间】:2020-08-04 05:30:58 【问题描述】:

我正在使用 react js 为网站构建前端。一个快速服务器(它是一个微服务)位于前端和 MongoDB 之间。我随时随地使用 GET、POST、PUT 从 react js 调用 Axios 到 express 服务器(URL = http://localhost:5688/chat)。

如下所示

客户端

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

服务器端

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');
);

以上是我实现 GET 调用的方式。同样,我也实现了 POST 和 PUT 方法。

PS:我删除了很多对这个问题没有太大帮助的中间代码

现在我想使用MongoDB change stream 来监听我在 MongoDB 上的集合发生的所有更改。我知道教程展示了我们如何在快速服务器中记录更新的文档.....例如tutorial。这使得我的快速服务器可以在我的数据库中的数据发生更改时获取所有更新的文档。

但我不确定如何将这些新数据传递给我的客户端,以便我可以使用这些新数据更新我的反应组件的状态。

如何让位于浏览器中的前端代码持续监听我的 express 服务器(一个 REST API),该服务器已经在更改流的帮助下不断监听 MongoDB 中的所有更改?

套接字是让我的客户端持续监听我的服务器的唯一方法吗?如果是这样,我将如何将来自 MongoDB 流的新数据传递到快速服务器上的套接字

如果我应该提供更多详细信息,请告诉我。非常感谢。

【问题讨论】:

【参考方案1】:

套接字是让我的客户端监听我的服务器的唯一方法吗?

嗯,是的。套接字连接是您必须使用类似socket.io 或其他套接字实现的唯一方法。

但是nodejs 的概念与维护socket 连接相反,因为当您的连接数量增加时,这可能会变得很昂贵。

我觉得更好更可靠的解决方案是每隔x 秒(2-3 秒?)询问服务器“是否进行了更改”,如果是,请更新视图。

话虽如此,根据您在应用中保存的确切状态,这可能不是可行的解决方案。

【讨论】:

谢谢。是的,我现在正在考虑使用套接字,但我正在寻找是否有更好的解决方案,因为你提到的确切原因。由于我的用户群预计会增长,因此很难维持套接字连接。此外,我曾想过让我的客户端每 2-3 秒触发一次 GET 调用,但这会破坏让我的应用真正实时的目的。 请记住,没有什么是“真正实时的”,由于数据库的异步特性,即使使用套接字实现也会有一定的延迟。【参考方案2】:

我会给你一个我自己的生产项目的例子:

//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

);


【讨论】:

谢谢。但我假设您发布的代码来自您的服务器,对吗?我想变量changes 将拥有更新的文档。如何将该变量发送给我的客户端,以便我设置我的反应组件的状态? 因为 MongoDB watch 返回一个流,所以你可能不得不使用 socket io 或 web socket 之类的东西来将更改推送到前端。 哦,谢谢。我目前正在查看如何使用套接字进行设置,但我不确定这是否是最佳解决方案。另外,您知道将数据从 MongoDB 监视流传递到套接字的任何资源或教程吗? 我个人不知道有没有把两者结合的教程。但是有很多关于 WebSocket 尤其是 socket io 的教程。不过,如果你需要,我可以给你一些示例代码。 抱歉耽搁了@Aviv 非常感谢您的回答。我忙了两天,我还没有尝试你的答案。反正我现在接受了。如果有任何其他困难,我会在这里告诉你。

以上是关于如何通过 REST API 微服务(使用 Express 构建)将 MongoDB 更改流与节点 js 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SPARK/Flink 流数据处理创建为微服务(REST API)

如何在微服务中处理从 UI 到 API 的 REST 调用

如何通过 REST API 在 Express Gateway 中使用多个路径和端点?

在WePay上将API从REST迁移到gRPC

进行微服务 REST API 版本控制的最佳方法是啥?

使用 Spring Boot 保护移动应用程序和微服务的 Rest API [关闭]