I am using request-promise npm lib for making multipart requestes from NodeJS app to Java Jersey 2.0 API backend. Since request uses form-data lib to make calls, I see it can only send strings, buffers and streams.
On the java backend side, I am expecting POJO objects as a@FormDataParams:
@GET
@ApiOperation(
value = "Gets party metadata by party_id",
notes = "Gets party metadata by party_id"
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "metadata")
})
@Path("party")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Metadata getByPartyId(
@ApiParam(value = "partyId", required = true) @NotNull @QueryParam("partyId") String partyId,
@ApiParam(value = "party metadata", required = true) @FormDataParam("metadata") Metadata metadata
) {
return folderCtrl.getByPartyId(partyId);
}
there are endpoints where I even wait for multiple POJO objects to come and I am using annotation validation mechanism to validate them upon receiving to the endpoint. Until now, I was able to simulate desired behaviour because I was sending these POJOs as a file containing JSON data. Jersey/Jackson was able to transform this to the POJO and continue in it's lifecycle...
Now, I need to call these endpoints from NodeJS. So, with that I know what can be sent with form-data I think I need an option to convert JSON object to stream and send it as in previous scenario to receive POJO objects.
So my question is, how to "streamify" objects in NodeJS and send them with request-promise ?
this is what I have now:
'use strict';
var rp = require('request-promise');
var express = require('express');
var fs = require('fs');
var metaJson = require(__dirname + '/attachments/metadata.json');
var router = express.Router();
const Readable = require('readable-stream').Readable;
const stream = Readable({objectMode: true});
stream._read = () => {};
const PROTOCOL = 'http://';
const HOST = 'localhost:';
const PORT = 8080;
// define the home page route
router.get('/', async function (req, res) {
stream.push(metaJson);
const options = {
method: req.method,
json: true,
baseUrl: PROTOCOL + HOST + PORT,
uri: req.originalUrl,
qs: {
partyId: "qwer"
},
formData: {
metadata: stream
},
};
try {
const response = await rp(options);
} catch (err) {
console.log(err);
}
res.send('foo res');
});
but that's ending up with this error:
_http_outgoing.js:502
throw new TypeError('First argument must be a string or Buffer');
^
TypeError: First argument must be a string or Buffer
at ClientRequest.write (_http_outgoing.js:502:11)
at Request.write (/home/tepo/IdeaProjects/rig/node_modules/request/request.js:1514:27)
at FormData.ondata (internal/streams/legacy.js:16:26)
at emitOne (events.js:96:13)
at FormData.emit (events.js:191:7)
at FormData.CombinedStream.write (/home/tepo/IdeaProjects/rig/node_modules/combined-stream/lib/combined_stream.js:118:8)
at DelayedStream.ondata (internal/streams/legacy.js:16:26)
at emitOne (events.js:96:13)
at DelayedStream.emit (events.js:191:7)
at DelayedStream._handleEmit (/home/tepo/IdeaProjects/rig/node_modules/delayed-stream/lib/delayed_stream.js:82:15)
at Readable.source.emit (/home/tepo/IdeaProjects/rig/node_modules/delayed-stream/lib/delayed_stream.js:29:19)
at Readable.read (/home/tepo/IdeaProjects/rig/node_modules/readable-stream/lib/_stream_readable.js:386:26)
at flow (/home/tepo/IdeaProjects/rig/node_modules/readable-stream/lib/_stream_readable.js:734:34)
at resume_ (/home/tepo/IdeaProjects/rig/node_modules/readable-stream/lib/_stream_readable.js:717:3)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
via greengold
No comments:
Post a Comment