0

In some page I have to get information from 8 different endpoints. 2 of them are outside of my application and sometimes they cause an delay at displaying data. The web browser waits until the data is processed. Once they're outside of my app I can't refactor them in order to make them fast, but I need to show the information that they provide. In addition, sometimes one of them returns nothing. If so, I use default data to show to the user. The waiting time takes time for the user experience perspective.

I'm using promises to call these endpoints. Below is part of the code snippet that I am using.

The code is working fine. The issue is the delay.

First. Here is the array that contains all the service that I need to process:

        var requests = [{
            // 0
            url: urlLocalApi + '/endpointURL_1/',
            headers: {
                'headers': 'apitoken'
            },
        }, {
            // 1
            url: urlLocalApi + '/endpointURL_2/',
            headers: {
                'headers': 'apitoken'
            },
        ];

The code of array is encapsulated in this method:

    const requests = homePageFunctions.createRequest();

Now, it is how the data is processed. I am using both 'request-promise' and 'bluebird', and a personal logger to check it out if everything goes fine.

const Promise = require("bluebird");
const request = require('request-promise');

var viewsHelper = {
    getPageData: function (requests) {
        return Promise.map(requests, function (obj) {
            return request(obj).then(function (body) {
                AppLogger.log(`Endpoint parsed`, statusLogger.infodate);
                return JSON.parse(body);
            });
        });
    }
}

module.exports = viewsHelper;

How do I call this?

    viewsHelper.getPageData(requests)
        .then(results => {
            var output = [];
            for (var i = 0; i < results.length; i++) {
                output.push(results[i]);
            }

            // render data
            res.render('homepage/index', output);
            AppLogger.log(`PageData is rendered`, statusLogger.infodate);
        })
        .catch(err => {
            console.log(err);
        });
};

Take a look that inside of each index item of "output" array, there is the output of each data of each endpoint.

The problem here is:

If any of the endpoint takes long, the entire chain slows even though if they are already processed. The web page waits in a blank mode.

How to prevent this behavior?

  • "*even if they are already processed*" - but not *all* of them are processed, and it seems like you need to wait for all results before rendering them to html. Or is that not what you want? – Bergi Jun 12 '20 at 13:08
  • "*They're outside of my app I can't refactor them in order to make them fast*" - consider caching the results on your side. – Bergi Jun 12 '20 at 13:08
  • @bergi. Yes, I need to wait. But if it takes long, there are also other data to be displayed. What I thinking is that I would need to used Angular instead this approach to load these data. Another option is to remove the lazy endpoints to another specific view. – Olavo Alexandrino Jun 12 '20 at 13:20
  • 1
    Ah, I thought you wanted to show the fallback values only if it responds with no data. If you also want to use it when it takes too long, that's what [timeouts](https://stackoverflow.com/q/37120240/1048572) are for. And yes, serving the page without content but then lazy-loading the individual parts would also work, but that's a completely different approach. – Bergi Jun 12 '20 at 13:25
  • yes. I found this video. I am not sure but It appears to be a suitable solution for the case that I have shared here. Take a look => https://www.youtube.com/watch?v=U8wffcXm-TM – Olavo Alexandrino Jun 13 '20 at 17:25

1 Answers1

1

That is an interesting question but I have questions in order to answer it effectively.

You have Node server and client (HTML/JS)

You have 8 end points 2 are slow because you don’t have control over them.

  1. Does the client (page) aware of the 8 end points? I .e you make 8 calls everytime you reload the page?

OR

  1. Does the page makes one request to your node JS and your nodeJS synchronously calls the 8 end points

If it is 1 then lazy loading will work easily for you since the page is making the requests.

If it is 2 lazy loading will work only at the server side however the client will be blocked because it doesn’t know (or care how you load your data. The page made one request and it is blocked waiting for that request..

Obviously each method has pros and cons ..

One way you can solve this is to asynchronously call those end points on node and cache them and when the page makes the 1 request you have the data ready ..

Again we know very little about the situation there are many ways to solve this

Hope this helps

Hussein Nasser
  • 402
  • 1
  • 6
  • 11
  • Hello! It's exactly as the second option that you said. If you know some code snippet or even a link with some situation like this, please, share it. I am about to be convinced that the best option is to convert the home page (with these 8 calls) to angular single page application. Thanks for answering. – Olavo Alexandrino Jun 14 '20 at 05:04