Search code examples
javascriptnode.jsmicroservices

Javascript library to collect objects properties, do batch processing and map results back to objects


For array of objects:

[
    {id: 1, name: "test", tagId: 1},
    {id: 2, name: "test", tagId: 15},
    {id: 3, name: "test", tagId: 5},
]

Need to reduce list of specific properties (tagId) to unique array [1,15,5], call some batch processing method, for example, doing http request for API for list of entities:

async (ids) => await axios.get('http://apihost/tag', {id: ids})

For result array of objects:

[
    {id: 1, name: "tag1"},
    {id: 15, name: "tag2"},
    {id: 5, name: "tag3"},
]

Finally need to map this objects by ID attribute to original array of objects matching by result.id => original.tagId, in fact doing an SQL join of two arrays to get this (like https://github.com/mtraynham/lodash-joins):

[
    {id: 1, name: "test", tagId: 1, tag: {id: 1, name: "tag1"}},
    {id: 2, name: "test", tagId: 15, tag: {id: 15, name: "tag2"}},
    {id: 3, name: "test", tagId: 5, tag: {id: 5, name: "tag3"}},
]

I'm already wrote a PHP library for this with API like:

new BulkMap(source).map(
  'tagId',
  'tag',
  async (ids) => axios.get('http://apihost/tag', {id: ids})
);

But now i need this in JS. Is there any Javascript/NodeJS library to do so? It looks like pretty common used pattern for microservices.


Solution

  • I like @RiverTam solution https://stackoverflow.com/a/50629965/962746. The only thing to fix is: multiple objects in source array can have the same tagId, so i'm index response objects instead of source objects:

    const lodashUniq = require('lodash.uniq');
    const lodashMap = require('lodash.map');
    
    const source = [
        {id: 1, name: "test", tagId: 1},
        {id: 2, name: "test", tagId: 15},
        {id: 3, name: "test", tagId: 5},
    ];
    
    const uniqueIds = lodashUniq(lodashMap(source, 'tagId'));
    const tags = await axios.get('http://apihost/tag', { id: uniqueIds });
    
    const tagsIndex = new Map(tags.map(tag => [tag.id, tag]));
    const result = source.map(s => (
        {... s, tag: tagsIndex.get(s.tagId)}
    ));