Example Using the REST Platform API: Listing all APIs

๐Ÿ“˜

Example only

The following code shows an example of using the REST Platform API. It is provided "as is" and is not supported by Rapid's support team.

The following Node.js code demonstrates how to use the REST Platform API to list all APIs in the Enterprise Hub. This can be useful for cleanup and governance of your Enterprise Hub.

This example assumes that the getAllAPIs.js and config.json files (shown below) are in the same directory.

You must set proper values for your Enterprise Hub (for example, for the API key) in the config.json file.

You can configure the fields in the config.json file to modify the results in the following ways:

  • Display APIs owned by teams (displayUserAPIs)
  • Display APIs owned by users (displayTeamAPIs)
  • Display public APIs (displayPublicAPIs)
  • Display private APIs (displayPrivateAPIs)
  • Display only APIs of a single category (displayCategory)

Setting a value of true for the first four fields and all for the fifth field above will display all APIs in your Enterprise Hub.

The sample code

const axios = require("axios").default;

let optionsCommon;

let resultsLog = []; //used to log messages and a subset of the data obtained

// set specific Enterprise Hub urls, key, category and preferences in config.json
let config = require("./config.json");

optionsCommon = {
  headers: {
    "x-rapidapi-host": config.rapidapi_host,
    "x-rapidapi-key": config.key,
  },
};

runAll();

async function runAll() {
  if (!config.displayTeamAPIs && !config.displayUserAPIs) {
    resultsLog.push(
      `Nothing to do because config.json has false for displayTeamAPIs and displayUserAPIs.`
    );
    displayResultsLog();
    return;
  }

  if (!config.displayPublicAPIs && !config.displayPrivateAPIs) {
    resultsLog.push(
      `Nothing to do because config.json has false for displayPublicAPIs and displayPrivateAPIs.`
    );
    displayResultsLog();
    return;
  }

  let results = {};

  results = await getUsers(results);

  if (config.displayTeamAPIs) {
    results = await getOrgs(results);

    results = await getEntityRolesForUsers(results);

    results = convertUserEntityRolesToOrgAdminArray(results);
    //resultsLog.push(`Orgs array: ${JSON.stringify(results.orgs)}`);

    results = await getTeamsByOrg(results);

    results = await getAPIsOwnedByOrgs(results);
  }

  if (config.displayUserAPIs) {
    results = await getAPIsOwnedByUsers(results);
  }

  logResults(results);
  return;
}

async function getUsers(resultObj = {}) {
  const optionsUnique = {
    method: "GET",
    url: `${config.base_url}admin/users`,
    params: { limit: "5000" },
  };
  const options = { ...optionsCommon, ...optionsUnique };
  let response = await axios.request(options);
  let locResults = {};
  locResults.users = response.data;
  return (resultObj = { ...resultObj, ...locResults });
}

async function getOrgs(resultObj = {}) {
  const optionsUnique = {
    method: "GET",
    url: `${config.base_url}admin/organizations`,
    params: { limit: "200", status: "ACTIVE" },
  };
  const options = { ...optionsCommon, ...optionsUnique };
  let response = await axios.request(options);
  let locResults = {};
  locResults.orgs = response.data;
  return (resultObj = { ...resultObj, ...locResults });
}

async function getEntityRolesForUsers(resultObj) {
  if (!Array.isArray(resultObj.users) || !resultObj.users.length)
    throw new Error(
      "getEntityRolesForUsers was called without a valid resultObj.users array"
    );
  let promises = [];
  resultObj.entityRoles = [];
  resultObj.users.forEach((user) =>
    promises.push(getEntityRolesForUser(user.id))
  );
  await Promise.all(promises);
  return resultObj;
  async function getEntityRolesForUser(userID) {
    const optionsUnique = {
      method: "GET",
      url: `${config.base_url}admin/entities/${userID}/roles`,
    };
    const options = { ...optionsCommon, ...optionsUnique };
    let response = await axios.request(options);
    if (response?.data?.length > 0) {
      resultObj.users.forEach((user) => {
        if (userID === user.id) user.entityRoles = response.data;
      });
    }
  }
}

function convertUserEntityRolesToOrgAdminArray(resultObj) {
  if (!Array.isArray(resultObj.users) || !resultObj.users.length)
    throw new Error(
      "convertUserEntityRolesToOrgAdmin was called without a valid resultObj.users array"
    );
  if (!Array.isArray(resultObj.orgs) || !resultObj.orgs.length)
    throw new Error(
      "convertUserEntityRolesToOrgAdmin was called without a valid resultObj.orgs array"
    );
  resultObj.users.forEach((user) => {
    if (user.entityRoles) {
      user.orgsAsAdmin = [];
      user.entityRoles.forEach((role) => {
        if (role.orgId && role.role.name === "Admin") {
          user.orgsAsAdmin.push(role.orgId);
          resultObj.orgs.forEach((org) => {
            if (org.id === role.orgId) {
              if (!org.admins) org.admins = [];
              org.admins.push(user.id);
            }
          });
        }
      });
      user.entityRoles = "cleared";
    }
  });
  return resultObj;
}

async function getTeamsByOrg(resultObj) {
  if (!Array.isArray(resultObj.orgs) || !resultObj.orgs.length)
    throw new Error(
      "getTeamsByOrg was called without a valid resultObj.orgs array"
    );
  let promises = [];
  resultObj.orgs.forEach((org) => promises.push(getTeamsForOrg(org.id)));
  await Promise.all(promises);
  return resultObj;
  async function getTeamsForOrg(orgID) {
    const optionsUnique = {
      method: "GET",
      url: `${config.base_url}organizations/${orgID}/teams`,
    };
    const options = { ...optionsCommon, ...optionsUnique };
    options.headers["on-behalf-of"] = getAnAdminForOrg(orgID);
    let response = await axios.request(options);
    if (response.data?.length > 0) {
      resultObj.orgs.forEach((org) => {
        if (orgID === org.id) org.teams = response.data;
      });
    }
  }

  function getAnAdminForOrg(orgID) {
    let match;
    resultObj.orgs.forEach((org) => {
      if (org.id == orgID) {
        match = org.admins[0];
      }
    });
    if (match) return match;
    console.log(`Couldn't find an org admin for ${orgID}`);
    resultsLog.push(`Couldn't find an org admin for ${orgID}`);
    return null;
  }
}

async function getAPIsOwnedByOrgs(resultObj) {
  // fills orgs[].apisOwned[]
  if (!Array.isArray(resultObj.orgs) || !resultObj.orgs.length)
    throw new Error(
      "getAllAPIsOwnedByTeams was called without a valid resultObj.orgs array"
    );
  let promises = [];
  resultObj.orgs.forEach((org) => promises.push(getAPIsOwnedByOrg(org)));
  await Promise.all(promises);
  return resultObj;
}

async function getAPIsOwnedByOrg(org) {
  if (!Array.isArray(org.teams) || !org.teams.length) {
    org.apisOwned = [];
  } else {
    let promises = [];
    org.teams.forEach((team) => {
      promises.push(getAPIsOwnedByTeam(team.id, team.name, "PUBLIC"));
      promises.push(getAPIsOwnedByTeam(team.id, team.name, "PRIVATE"));
    });
    await Promise.all(promises);
  }
  return org;

  async function getAPIsOwnedByTeam(teamID, teamName, visibility = "PUBLIC") {
    const optionsUnique = {
      method: "GET",
      url: `${config.base_url}apis`,
      params: { visibility: visibility, ownerId: teamID },
    };
    const options = { ...optionsCommon, ...optionsUnique };
    options.headers["on-behalf-of"] = teamID;
    let response = await axios.request(options);
    if (response?.data?.length > 0) {
      if (!org.apisOwned) {
        org.apisOwned = [];
      }
      response.data.forEach((api) => {
        api.teamName = teamName;
        if (
          config.displayCategory.trim().toLowerCase() === "all" ||
          api.category.trim().toLowerCase() ===
            config.displayCategory.trim().toLowerCase()
        ) {
          org.apisOwned.push(api);
        }
      });
    }
  }
}

async function getAPIsOwnedByUsers(resultObj) {
  // fills users[].apisOwned[]
  if (!Array.isArray(resultObj.users) || !resultObj.users.length)
    throw new Error(
      "getAllAPIsOwnedByUsers was called without a valid resultObj.users array"
    );

  let promises = [];
  resultObj.users.forEach((user) =>
    promises.push(getAPIsOwnedByUserA(user, resultObj))
  );
  await Promise.all(promises);
  return resultObj;
}

async function getAPIsOwnedByUserA(user, resultObj) {
  let promises = [];
  promises.push(getAPIsOwnedByUserB(user.id, "PUBLIC"));
  promises.push(getAPIsOwnedByUserB(user.id, "PRIVATE"));
  await Promise.all(promises);

  async function getAPIsOwnedByUserB(userID, visibility = "PUBLIC") {
    const optionsUnique = {
      method: "GET",
      url: `${config.base_url}apis`,
      params: { visibility: visibility, ownerId: userID },
    };
    const options = { ...optionsCommon, ...optionsUnique };
    options.headers["on-behalf-of"] = userID;
    let response = await axios.request(options);
    if (response?.data?.length > 0) {
      if (!user.apisOwned) {
        user.apisOwned = [];
      }
      response.data.forEach((api) => {
        if (
          config.displayCategory.trim().toLowerCase() === "all" ||
          api.category.trim().toLowerCase() ===
            config.displayCategory.trim().toLowerCase()
        ) {
          user.apisOwned.push(api);
        }
      });
    }
  }
}

function logResults(results) {
  // resultsLog.push(`There are ${results.orgs.length} orgs in the Hub.`);

  let privateAPIsOwnedByTeams = 0;
  let publicAPIsOwnedByTeams = 0;
  let privateAPIsOwnedByUsers = 0;
  let publicAPIsOwnedByUsers = 0;

  if (config.displayTeamAPIs) {
    let teamAPICounter = 0;
    results.orgs.forEach((org) => {
      if (org.apisOwned?.length) {
        if (config.displayPrivateAPIs && config.displayPublicAPIs) {
          resultsLog.push(
            `Org ${org.name} has ${org.teams.length} team(s) and owns ${
              org.apisOwned?.length || 0
            } API(s).`
          );
        }
        org.apisOwned?.forEach((api) => {
          if (api.visibility === "PUBLIC" && config.displayPublicAPIs) {
            publicAPIsOwnedByTeams++;
            teamAPICounter++;
            resultsLog.push(
              `   ${teamAPICounter}. ${api.name} (${api.visibility}) cat: ${api.category} owner: ${org.name} ${api.teamName}`
            );
          }
          if (api.visibility === "PRIVATE" && config.displayPrivateAPIs) {
            privateAPIsOwnedByTeams++;
            teamAPICounter++;
            resultsLog.push(
              `   ${teamAPICounter}. ${api.name} (${api.visibility}) cat: ${api.category} owner: ${org.name} ${api.teamName}`
            );
          }
        });
      }
    });
  }

  if (config.displayUserAPIs) {
    resultsLog.push("");
    resultsLog.push("USER APIS:");
    // resultsLog.push(`There are ${results.users.length} users in the Hub.`);
  }

  let userAPICounter = 0;
  results.users.forEach((user) => {
    if (user.apisOwned?.length) {
      user.apisOwned?.forEach((api) => {
        if (api.visibility === "PUBLIC" && config.displayPublicAPIs) {
          publicAPIsOwnedByUsers++;
          userAPICounter++;
          resultsLog.push(
            `   ${userAPICounter}. ${api.name} (${api.visibility}) cat: ${api.category} owner: ${user.name}`
          );
        }
        if (api.visibility === "PRIVATE" && config.displayPrivateAPIs) {
          privateAPIsOwnedByUsers++;
          userAPICounter++;
          resultsLog.push(
            `   ${userAPICounter}. ${api.name} (${api.visibility}) cat: ${api.category} owner: ${user.name}`
          );
        }
        if (!user.name) {
          // resultsLog.push(`    WARNING: ${api.name} (${api.id}) has no owner.`);
        }
      });
    }
  });

  resultsLog.unshift("");

  if (config.displayUserAPIs) {
    if (config.displayPrivateAPIs) {
      if (config.displayPublicAPIs || config.displayTeamAPIs) {
        //avoid a repetitive log entry
        resultsLog.unshift(
          `There are ${privateAPIsOwnedByUsers} private APIs owned by users`
        );
      }
    }
    if (config.displayPublicAPIs) {
      if (config.displayPrivateAPIs || config.displayTeamAPIs) {
        //avoid a repetitive log entry
        resultsLog.unshift(
          `There are ${publicAPIsOwnedByUsers} public APIs owned by users`
        );
      }
    }
  }

  if (config.displayTeamAPIs) {
    if (config.displayPrivateAPIs) {
      if (config.displayPublicAPIs || config.displayUserAPIs) {
        resultsLog.unshift(
          `There are ${privateAPIsOwnedByTeams} private APIs owned by teams`
        );
      }
    }

    if (config.displayPublicAPIs) {
      if (config.displayPrivateAPIs || config.displayUserAPIs) {
        resultsLog.unshift(
          `There are ${publicAPIsOwnedByTeams} public APIs owned by teams`
        );
      }
    }
  }

  let wordingVisiblity = "";
  if (!config.displayPrivateAPIs) wordingVisiblity = "public ";
  if (!config.displayPublicAPIs) wordingVisiblity = "private ";
  let wordingOwnedBy = "";
  if (!config.displayTeamAPIs) wordingOwnedBy = "owned by users";
  if (!config.displayUserAPIs) wordingOwnedBy = "owned by teams";
  resultsLog.unshift(
    `There are ${
      publicAPIsOwnedByTeams +
      publicAPIsOwnedByUsers +
      privateAPIsOwnedByTeams +
      privateAPIsOwnedByUsers
    } ${wordingVisiblity}APIs ${wordingOwnedBy}`
  );

  resultsLog.unshift("");
  resultsLog.unshift(`Category displayed: ${config.displayCategory}`);

  displayResultsLog();
}

function displayResultsLog() {
  resultsLog.forEach((entry) => console.log(entry));
}

The configuration file

The first three fields below can be obtained by viewing a code snippet when testing a REST Platform API endpoint in your API Hub. Because the code above uses the on-behalf-of header, the key used must have Environment Access to the REST Platform API.

{
    "rapidapi_host": "YOURVALUE.YOURVALUE.rapidapi.com",
    "key": "YOURVALUE",
    "base_url": "https://YOURVALUE.p.rapidapi.com/v1/",
    "displayUserAPIs": true,
    "displayTeamAPIs": true,
    "displayPublicAPIs": true,
    "displayPrivateAPIs": true,
    "displayCategory": "Other",
    "helpForDisplayCategoryField": "enter 'all' above to display APIs from all categories"
}

Sample output

Display all APIs with a category of Data.

1502