NodeJS Stream:将JSON从输入流转换为输出流并更改某些值

时间:2016-10-28 20:07:53

标签: node.js

我几天来一直在摸不着解决这个问题。我想从HTTP请求流式传输的相对较大的JSON字符串中更改某个键的值,然后将其流式传输到客户端。假装这是一个很大的JSON:

{
 "name":"George", 
 "country": {
      "home": "United States",
      "current": "Canada"
 }
}

我希望通过更改name.country.current

来输出
{
 "name":"George", 
 "country": {
      "home": "United States",
      "current": "Indonesia"
 }
}

转换是在一个restify处理程序中完成的:

let proxyHandler = function(req, res, next) {
  let proxyReq = http.request(opt, r => {
    r.on('data', data => {
      // transform here and send the data using response.write();
      // and close the response object
      // when the parsing ends
  });
  proxyReq.end();
  next();
}

我无法使用JSON.parse因为JSON的大小很大,所以我需要在它到达时对其进行流式传输/解析/转换。那里有没有能够这样做的图书馆?

我尝试过使用stream-json,但是当我需要组合变换流时它很慢。当我发起大量请求时,它只是爬行然后超时。

由于客户端未发送Content-Length标头,因此服务器需要关闭该流。

更新

我知道有一个流式JSON解析器。然而,我需要的不仅是解析器,还有发射器。这个过程将是

JSON - >解析(基于事件) - >转换解析事件 - >发出转换后的JSON。所有这些都需要在NodeJS stream中完成。

正如我上面提到的,我已经使用了stream-json,我编写了基于堆栈的发射器,但是当很多请求进来时它很慢并且产生了背压。我问的是否有任何请求那个能够一次性处理的节点库。理想情况下,库可以像下面这样执行:

// JSONTransform is a hypotetical library class
result
  .pipe(new JSONTransform('name.country.home', (val) => 'Indonesia')
  .pipe(response)

1 个答案:

答案 0 :(得分:0)

假设您要更改foo.bar.jar的属性 伪步骤可以如下:

  1. 缓冲您的数据,直至找到“{”标记(例如:Buffer ='foo:{')
  2. 从Buffer中获取属性名称,将缓冲区响应流式传输并清除
  3. 属性名称是否与'foo'匹配

    • 如果没有,继续向下传输响应,直到找到结束“}”标记(跳过中间的所有属性)。 重复步骤1至步骤3
    • 如果是,请执行步骤4
  4. 重复步骤1至步骤3,此时仅检查属性名称匹配'bar'