通过Hapi流MongoDB查询响应到客户端的最佳方法是什么?我已经看到了一些使用http或request的例子,但不满意。
问题是,我得到连接和字符串化JSON对象在客户端,但我不能不能调用JSON。解析结果,因为它不是有效的JSON。
我看到的一些解决方案建议在发送到客户端之前在服务器端进行连接,但这似乎破坏了流的价值。
例如:const Hapi = require('hapi'),
MongoClient = require('mongodb').MongoClient,
Readable = require('stream').Readable;
// Connection url
const url = 'mongodb://localhost:27017/test';
// Create a server with a host and port
const server = new Hapi.Server();
server.connection({
host: 'localhost',
port: 8000
});
// Add the route
server.route({
method: 'GET',
path: '/stream',
handler: function (request, reply) {
let docs = [{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 3 }, { a: 4, b: 4 }];
// Connect using MongoClient
MongoClient.connect(url, (err, db) => {
// Create a collection we want to drop later
const col = db.collection('stream_example');
// Insert documents into collection
col.insertMany(docs, { w: 1 }, function (err) {
if (err) return console.log(err);
// Peform a find to get a cursor
const stream = col.find()
.stream({
transform: function (doc) {
return JSON.stringify(doc);
}
});
reply(new Readable().wrap(stream));
});
});
}
});
// Start the server
server.start(err => {
if (err) {
throw err;
}
console.log('Server running at:', server.info.uri);
});
返回响应。结果:
" {" _id ":"57 b0b99d681bb97a9321f03e","一个":1、"b":1}{" _id ":"57 b0b99d681bb97a9321f03f","一个":2,"b":2}{" _id ":"57 b0b99d681bb97a9321f040","一个":3,"b":3}{" _id ":"57 b0b99d681bb97a9321f041","一个":4,"b":4}"
这是一个无效的JSON,不能被解析。
我已经尝试将此流管道到事件流模块的.join('n')流中以添加换行符,同时还在前后推字符串"["one_answers"]"以构建字符串化的JSON数组,但尚未成功。反正这感觉太俗气了。
有更好的方法吗?
必须使用流转换来发送有效的JSON。
基本上你必须:
-
用
启动流'['
-
然后附加
stringified JSON object
-
在每个对象后面添加
','
-
结束流与
']'
[
{'key': 'value'},
{'key': 'value'},
]
一些解决方案:
http://andyfiedler.com/2017/01/mongodb-stream-to-hapi https://github.com/nlindley/hapi-mongo-stream https://github.com/dominictarr/JSONStream下面是我如何在Hapi中使用Mongo的一个例子。
从BoardRepo.js:module.exports = {
GetAllBoards: function (facility) {
return new Promise(function (resolve, reject) {
var db = mongo.ETestDatabase;
db.collection('boards').find({ "Location.Facility": facility }).toArray().then(r => {
resolve(r);
}).catch(err => {
logger.error('Error getting all boards by facility - ' + err.message);
reject(err.message);
});
});
}
};
在Hapi处理程序(BoardHandler.js)中:
module.exports = {
GetAllBoards: {
method: 'GET',
path: '/v1/boards/facility/all/{facility}',
config: {
auth: 'jwt',
plugins: { 'hapiAuthorization': { roles: ['ADMINISTRATOR', 'MANAGER', 'TECHNICIAN', 'OPERATOR'] } },
description: 'Gets all boards per facility',
tags: ['api'],
handler: (request, reply) => {
logger.info('[' + request.auth.credentials.username + '] GetAllBoards requested');
var facility = request.params.facility;
repo.GetAllBoards(facility)
.then(boards => {
if (boards !== null) {
reply(boards);
} else {
reply().code(404);
}
})
.catch(err => {
geh.HandleError(request.auth.credentials.username, err, reply);
});
}
}
}
};