0

I'm trying to create REST service that returns data from database as a response via hapi.js.

I'm using tedious to execute SQL queries and I want to format results as JSON or XML and return them as a response of hapi request. Note that this is not tedious-specific, I can have the same problem with any database. Tedious has a callback that is invoked each time it receives a new row from the result set:

sqlRequest.on('row', function (columns) {
        fnOutput(columns[0].value);
});

This is the simplest example with one column output. fnOutput is a custom function that accepts text that should be returned. It can concatenate results and format them as JSON that will be returned to client.

I'm getting row-by-row and I want to concatenate values in rows and return them to the client via hapi. How to continuously send partial results to the response?

  1. I don't want to concatenate all rows in this callback and then push entire formatted JSON when the query is finished. I don't know how many records I will have and I want to avoid big strings that will be accumulated.
  2. If I try to call reply(columns[0].value) in fnOutput each time I get new row, it fails when second row is returned with: "reply interface called twice"

Is there some way to continuously append results in this callback to hapi.js output stream each time I get new row in callback function?

Jovan MSFT
  • 13,232
  • 4
  • 40
  • 55
  • What version of hapi? – arb Jan 19 '16 at 20:29
  • Latest version ^12.1.0 – Jovan MSFT Jan 21 '16 at 21:51
  • Does the database driver you are using support streaming results? – arb Jan 22 '16 at 20:27
  • tedious is event based so it run callback every time it receives a new row. I have found some requests to support streaming but it seems that it is not implemented. – Jovan MSFT Jan 23 '16 at 22:22
  • I believe that I'm looking for something like response.write method from express http://stackoverflow.com/questions/18857693/does-express-js-support-sending-unbuffered-progressively-flushed-responses . Is there an equivalent or anything similar in hapijs. – Jovan MSFT Jan 23 '16 at 23:03

1 Answers1

1

You may be able to write the data to the raw response using request.raw.res.write()

request.raw.res is the raw ServerResponse object, and you can find the documentation for the write method here: https://nodejs.org/dist/latest-v4.x/docs/api/http.html#http_response_write_chunk_encoding_callback

Once you are done writing data, you'll need to tell hapi that you are done handling the request manually by calling reply.close()

Something similar to this (untested):

sqlRequest.on('row', function (columns) {
    request.raw.res.write(columns[0].value);
});

sqlRequest.on('done', function () {
    reply.continue();
});
mikefrey
  • 4,653
  • 3
  • 29
  • 40
  • You are right, this solved the problem. Instead of reply.continue() I have used request.raw.res.end() because I have passed entire reply.raw.res object to my function. If works great. – Jovan MSFT Jan 28 '16 at 12:01