NodeJS - Get data from Redash v6 API
Tags: redash, node, bigdata, analytics
Published: 2022-02-26 14:48:20

### [Salam Engineering sobat,]

Sobat engineering sudah kenal Redash? ya, itu salah satu wadah untuk Big-Query dimana banyak sekali jenis database yang bisa di koneksikan. Nah berikut saya akan paparkan gimana caranya sih get data API dari Redash ini (untuk API redash https://redash.io/help/user-guide/integrations-and-api/api/).


* redash_api.js
```javascript

const REDASH_API_URL = `http://redash.com/api/`;
const REDASH_API_KEY = `key-on-your-user-profile-in-redash`;
const fetch = require("node-fetch");

module.exports = {
  /**
   * {
      "job": {
        "status": 1,
        "error": "",
        "id": "String UUID",
        "query_result_id": null,
        "updated_at": 0
      }
    }
   * @param {*} id 
   */
  RedashCallAPI: async (id, obj_params = '') => {
    try {
      let p = null;
      const body = { max_age: 0 };

      // when use params
      const params = qs(obj_params);

      // sample: http://redash.com/api/queries/10/refresh?p_keyword=ulala%20test&p_start=2020-01-01&p_end=2020-01-02
      const res1 = await call(
        "POST",
        REDASH_API_URL + `queries/${id}/refresh${params}`,
        body
      ).catch((e) => {
        throw e;
      });

      if (res1.status == 200) p = await pool(res1.data.job);
      else return false;

      // get data results
      if (p.status == 4) return false;
      else {
        const res2 = await call(
          "GET",
          REDASH_API_URL + `query_results/${p.query_result_id}`
        ).catch((e) => {
          throw e;
        });

        if (res2.status == 200) return res2;
        else return false;
      }
    } catch (error) {
      console.log(`error => `, error);
    }
  },
};

/**
 *
 * @param {*} id
 * 1 == PENDING (waiting to be executed)
 * 2 == STARTED (executing)
 * 3 == SUCCESS
 * 4 == FAILURE
 * 5 == CANCELLED
 * @return {*} job
 */
function pool(obj) {
  return new Promise(async (o, x) => {
    let job = null;
    let status = null;

    while (status < 3) {
      const response = await call("GET", REDASH_API_URL + "jobs/" + obj.id);
      status = response.data.job.status;

      if (response.status == 200) job = response.data.job;
      else x(`error status: ${response.status}`);
    }

    o(job);
  });
}

/**
 * serialize query-string from {}
 * @param {*} obj
 */
function qs(obj) {
  let str = [];
  for (let p in obj)
    if (obj.hasOwnProperty(p)) {
      str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
    }

  return str.length > 0 ? "?" + str.join("&") : null;
}

/**
 *
 * @param {*} method
 * @param {*} path
 * @param {*} body
 */
async function call(method, url, body) {
  try {
    let c = {};
    if (method == "GET")
      c = {
        method: method,
        headers: {
          Authorization: `Key ${REDASH_API_KEY}`,
        },
      };
    else
      c = {
        method: method,
        body: JSON.stringify(body),
        headers: {
          Authorization: `Key ${REDASH_API_KEY}`,
        },
      };

    const response = await fetch(url, c);
    const data = await response;
    const json = await response.json();

    return {
      status: data.status,
      data: data.status == 200 ? json : null,
    };
  } catch (error) {
    throw Error(error);
  }
}
```

* index.js
``` javascript
const redash_api = require('./redash_api.js');
const run = async () => {
    try {
       // pastikan ada prefix `p_` untuk parameter
       const params = {
         p_keyword: 'cari ',
         p_start: '2020-01-01',
         p_end: '2020-01-02'
       }

       const data = await redash_api.RedashCallAPI(1,params);
       return data;
    } catch (error) { throw Error(error); }
}

run();
```