在NodeJS Express框架中处理批量REST API请求

我正在尝试为我的应用程序实现批处理API,并且客户端可以发送一组请求给服务器,并期望返回单个响应。

在我的MEAN栈应用程序中使用Express框架。 我已经创build了一个批量API资源,从客户端接收此资源,并应按照请求的每个部分中提到的URL行事。

样品请求正文:

{ "batchID": "abc123", "batchReq": [{ "id": "1", "url": "/api/schoolm/students", "method": "GET", "value": null }, { "id": "2", "url": "/api/schoolm/teachers", "method": "POST", "value": { "name": "Teacher1", "age": 34 } }] } 

这是发送到/ api /学校/批次

我怎样才能将批量控制器中的每个请求redirect到各自的API?

听起来就像你需要双重定义你的路由表。 你可以分解你的逻辑,所以你可以更容易地访问这些function。 定义一个StudentsControllerTeacherController ,这样你就可以定义Express路线了

 app.get('/api/schoolm/students', studentController.getStudents ); app.post('/api/schoolm/teachers', teachController.postTeachers ); 

但仍然可以在批处理方法中访问它们。 编辑:你可能想更多地分解主逻辑,所以你可以直接调用批处理方法。

 StudentController.prototype.getStudents = function(params, callback){ //do stuff callback( null, studentList ); } StudenController.prototype.getStudentsRequest = function( req, res ){ this.getStudents( {}, function( err, students ){ //check error res.send( students ); }); } //elsewhere, in routing table app.get('/api/schoolm/students', studentController.getStudentsRequest ); //elsewhere, in batching method //api route that matches students studentController.getStudents( batchReq[index].value, function(err, students){ //do something with students, like put in outer results object. //call async.each's callback(), or whatever for control flow } ); 

或者,您可以使假reqres对象直接调用控制器。 像节点嘲笑 – http 。

当然,您必须重新parsing批处理对象中指定的path,以便调用正确的控制器方法并存储结果。 也许像导演 (或任何内部expression使用)会有所帮助。

Express中的典型路由将在最后发送它们的响应,并且res.send也可以调用res.end ,所以您不能真正将它们传递给别处或在别处使用它们(因为不能调用res.end两次)。

尽pipe如此,为什么不从客户端发送多个请求。 那么你不必在客户端parsing出一个批处理响应。 我认为这会使你的

我的回答很大程度上是借用了粘土的回应。 而我只是添加了我所用的所有细节。 再次感谢你粘土!

首先是我的API的结构:

/api/schoolm是父api

从那里请求被redirect到子API:

 /api/schoolm/students/ /api/schoolm/teachers/ /api/schoolm/subjects/ ... 

现在,为了支持批处理操作,我添加了另外一个负责处理所有批处理事务的API。

 /api/schoolm/batch/ 

一个典型的批量请求将如下所示:

 { "batchReq":[ { "id":"1", "uri": "/api/schoolm/students/", "httpMethod": "GET" }, { "id":"2", "uri": "/api/schoolm/teachers/", "httpMethod": "GET" } ] } 

/api/schoolm/batch的控制器validation请求(业务逻辑)并用参考ID回应。

 var async = require('async'); var httpMocks = require('node-mocks-http'); var shortid = require('shortid'); exports.processBatch = function(batchRequests, callback){ var batchRes = {}; var result = {}; var batchID = shortid.generate(); result.batchID = batchID; async.setImmediate(function () { async.eachSeries(batchRequests, function(batchReq, callback){ var mockRes = httpMocks.createResponse({ eventEmitter: require('events').EventEmitter }); var reqDetails = _processSubRequest(batchReq); _fetchResponse(reqDetails, mockRes); mockRes.on('end',function(){ result[batchReq.id] = mockRes._getData(); callback(null); }); },function(err){ console.log(result); }); }); callback("Your batch request has been accepted. Request ID - "+batchID); } function _processSubRequest(batchReq){ var retValue = {}; var request = {}; var uriComp = batchReq.uri.split('/'); retValue.controller = uriComp[3]; request.method = batchReq.httpMethod; request.url = batchReq.uri; request.body = batchReq.body || {}; request.params = batchReq.params || {}; if(batchReq.httpMethod == 'GET'){ if(uriComp.length > 5){ request.params.id = uriComp[4]; } }else if(batchReq.httpMethod == 'POST'){ }else{ } retValue.request = request; return retValue; } function _fetchResponse(reqDetails, mockRes){ var mockReq = httpMocks.createRequest(reqDetails.request); // proceed to fetch answer from respective controller methods. ....................... } function _prepResponse(result, err, res){ var data = {}; if(err) { data["error"] = err; data["response"] = null; return data; }else{ data["error"] = null; data["response"] = result; return data; } } 

批量处理完成后,可以作为实时通知的一部分发送给用户,也可以存储在数据库中供以后读取。

打开GraphQL进行批量请求:)