Design to not make redundant calls for information

I have a design question about how best to get user data. I am displaying a list of reviews. Each review has a reviewer user id and a reviewee user id. The collection structure is like so:

{
    "_id": 24235,
    "reviewerId": 11254,
    "revieweeId": 29981,
    "rating": 5,
    "reviewText": "Lorem Ipsum"
}

The blaze template needs to show the reviewer’s avatar and firstname. I am having trouble figuring out how best to get these details? Should I publish a service? I will be showing a list of reviews so the service will be called for each user, isn’t that inefficient?

<ul class="review-list">
  {{#each reviews}}
    <li>
      <img src="{{reviewerAvatar}}"/>
      <p>{{reviewerName}}</p>
      <p>{{reviewText}}</p>
      <span>{{rating}}</span>
    </li>
  {{/each}}
</ul>

Heres the idea I have but can the design be improved so I don’t make too many unnecessary requests for user details?

Template.reviewItem.helpers({
  reviewerAvatar: function() {
    // is it inefficient to make this call for both reviewerAvatar and reviewerName?
    return Meteor.call('users.userDetails', this.reviewerId).avatar;
  },
  reviewerName: function() {
    return Meteor.call('users.userDetails', this.reviewerId).firstName;
  }
});

Yes this is very inefficient. You probably don’t need this to be reactive, so I would get all the info at once in one method call, and save that result in a reactive variable which you then display.

In the method on the server, use an aggregation to gather up a list of reviews with the reviewer name joined in. You can use sakulstra:aggregate to add an .aggregate method on your collections, and see the mongodb docs on aggregation.

1 Like

Generally speaking:

  1. Aim to make one call from client to server and also one call from server to DB for page load/component
  2. If you want speed up the read over write, de-normalize the collection, but then you need be mindful of avatar update
  3. If you still want to have normalized collection, use Mongo aggregates to do the join operations or Grapher from cult-of-coders.
  4. Always use projects to reduce the data fetched from the DB and the data sent to the client (specially with Meteor users, to prevent passing all the login history which will bloat your socket messages in addition to the security risks)

Making multiple calls to server/DB will surely kill the performance and overload the server/DB with little traffic.