Building a Lightweight Random JSON Generator with a Custom Vocabulary

April 28, 2023

Introduction

When it comes to generating random JSON data, there are libraries like Faker.js that can help you accomplish this. However, sometimes you might be in search of a lighter-weight solution that can run efficiently in a browser. In this article, we will discuss how to create a custom JSON generator that uses a limited vocabulary to generate random data.

Using a Small Custom Vocabulary

To keep our generator lightweight, we have chosen to use a small vocabulary consisting of:

  • Top 100 first names
  • Top 100 last names
  • Common nouns
  • Common phone area codes
  • List of 100 cities
  • List of 30 countries

By using this approach, we can generate a large amount of random data while keeping the generator light and efficient.

Implementing the Random JSON Generator

We searched internet to find lists of common words, cities etc and saved it into plain JS arrays like

export const top100Cities = [
    "Tokyo",
    "Delhi",
    "Shanghai",
    "São Paulo",
    "Mumbai",
    "Mexico City",
    "Beijing",
    ...
]

then we added a simple helper to pick random element from array

function randomFromArr(items) {
    return items[Math.floor(Math.random()*items.length)];
}

we used simple logic for now to determine field type based on field name, based on field name keywords we have different generators.

const fieldGenerators = [
    {'name': 'firstName', 'func': () => randomFromArr(top100FirstNames)},
    {'name': 'lastName', 'func': () => randomFromArr(top100LastNames)},
    {'name': 'name', 'func': () => `${randomFromArr(top100FirstNames)} ${randomFromArr(top100LastNames)}`},
    {'name': 'tag', 'func': () => `${randomFromArr(topNouns)}`},
    {'name': 'email', 'func': () => `${randomString(5).toLowerCase()}@${randomString(5).toLowerCase()}.com`},
    {'name': 'city', 'func': () => randomFromArr(top100Cities)},
    {'name': 'country', 'func': () => randomFromArr(top30Countries)},
    {'name': 'zipCode', 'func': () => getRandomInt(10000, 99999).toString()},
    {'name': 'phone', 'func': () => `(${randomFromArr(popularAreaCodes)}) ${getRandomInt(100, 999)}-${getRandomInt(1000, 9999)}`},
    {'name': 'id', 'func': () => getRandomInt(1, 1000)},
    {'name': 'date', 'func': () => new Date(getRandomInt(Date.parse('2000-01-01'), Date.now())).toISOString()}
];

there is also fallback with random string generations

const randomString = (length) => {
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return result;
};

Then there is main function that recursively walks the JSON object and for each field name and value, it generates random value.

const smartRandomJSON = (key, obj) => {
    if (typeof obj === 'string') {
        for (let i = 0; i < fieldGenerators.length; i++) {
            const {name, func} = fieldGenerators[i];
            console.log(key, name, key === name || key.toLowerCase().includes(name));
            if (key === name || key.toLowerCase().includes(name)) {
                const res = func();
                console.log(res);
                return func();
            }
        }
        return randomString(getRandomInt(5, 20));
    } else if (typeof obj === 'number') {
      return getRandomInt(1, 100);
    } else if (typeof obj === 'boolean') {
      return Math.random() >= 0.5;
    } else if (Array.isArray(obj)) {
      const length = getRandomInt(1, 5);
      return Array.from({ length }, () => smartRandomJSON(key, obj[0]));
    } else if (typeof obj === 'object') {
      const newObj = {};
      for (const key in obj) {
        newObj[key] = smartRandomJSON(key, obj[key]);
      }
      return newObj;
    }
  };

Demo

See the final result here at https://www.devtoolsdaily.com/generators/json/

--

this blog post was originally published on https://www.devtoolsdaily.com/blog/building-lightweight-json-generator/