node.jsjsonapiexpressrequestjs

Transforming a payload from requestjs before sending it to the client


Brothers and sisters, I am building an Express API Endpoint that needs to consume an external API, perform some changing of keys and values, and return to the result to the client. Here is what I have thus far:

const external_endpoint = <external_api_end_point>;

app.get('/', function (req, res, next) {

  request({ url: external_endpoint}).pipe(res);
});

This returns the exact payload you would get from hitting the external_endpoint directly.

Isn't there something I can do to change res before it gets sent to the client? I tried a few things but nothings has worked. Any ideas or best practices associated with doing a transform on the incoming payload?

For the sake of simplicity. Lets say this is the payload obj.json:

{
    "sad": {
        "userid": 5,
        "username": "jsmith",
        "isAdmin": true
    }
}

and I am wanting to change sad to happy.

I know outside of the request I could do something like this:

obj = JSON.parse(JSON.stringify(obj).split('"sad":').join('"happy":'));

but throwing obj in place of res will not work. I have tried assigning the value of this res and res.body but no dice.

Thanks for you help in advance!


Solution

  • If you're using request-promise, you can simply make a new response and send it, or modify the response you got back:

    app.get('/', function (req, res, next) {    
        request({ url: external_endpoint, json: true})
            .then(response => res.json({ happy: response.sad })))
            .catch(next);
    });
    

    (of course, you need to handle errors appropriately)

    If you want to process it as a stream (which makes sense if you have a massive amount of data), you can use the original request module, and use event-stream to create your pipe:

    const es = require('event-stream');
    
    const swapper = es.through(
        function write(data) {
            this.emit("data", data.replace("sad", "happy"));
        },
        function end() {
            this.emit("end");
        }
    );
    
    request({ url: external_endpoint})
        .pipe(es.stringify())
        .pipe(swapper)
        .pipe(es.parse())
        .pipe(res);
    

    Here's a sandbox to test the stream processing: https://codesandbox.io/s/3wqx67pq6