Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

External API Calls With Express, Node.JS and Require Module

I have a route as followed:

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    },
    function(error, response, body) {
      if (!error && response.statusCode === 200) {
        console.log(body)
      }
    }
  });
});

module.exports = router;

I'm trying to make an API call to the Giant Bomb API to bring back whatever data it has about World of Warcraft.

The problem is, the route just loads; it doesn't do anything or it doesn't time out, it's just continuous loading.

I don't know what I'm doing wrong, but that being said... I don't know what's right either. I'm trying to learn as I go along.

Any help would be great.

Thanks

like image 910
Dave Melia Avatar asked Sep 02 '16 21:09

Dave Melia


People also ask

What is require (' express ') in NodeJS?

ExpressJS is a NodeJS module; express is the name of the module, and also the name we typically give to the variable we use to refer to its main function in code such as what you quoted. NodeJS provides the require function, whose job is to load modules and give you access to their exports.


4 Answers

You need to take the data you get from request() and send it back as the response to the original web server request. It was just continuously loading because you never sent any sort of response to the original request, thus the browser was just sitting there waiting for a response to come back and eventually, it will time out.

Since request() supports streams, you can send back the data as the response very simply using .pipe() like this.

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    }
  }).pipe(res);
});

module.exports = router;

This will .pipe() the request() result into the res object and it will become the response to the original http request.

Related answer here: How to proxy request back as response


Edit in 2021. The request() library has now been deprecated and is no longer recommended for new code. There are many alternatives to choose from. My favorite is the got() library. The above could be accomplished using it like this. This also upgrades to use the pipeline() function which is a better version of .pipe() with more complete error handling.

const router = require('express').Router();
const got = require('got');
const { pipeline } = require('stream');

router.get('/', function(req, res) {
  const dataStream = got.stream({
      uri: 'http://www.giantbomb.com/api/search',
      qs: {
        api_key: '123456',
        query: 'World of Warcraft: Legion'
      }
  });
  pipeline(dataStream, res, (err) => {
      if (err) {
          console.log(err);
          res.sendStatus(500);
      }
  });
});

module.exports = router;
like image 99
jfriend00 Avatar answered Oct 25 '22 01:10

jfriend00


Per every route in Express, it is necessary to send a response (partial or complete) or call next, or do both. Your route handler does neither. Try

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    },
    function(error, response, body) {
      if (!error && response.statusCode === 200) {
        console.log(body);
        res.json(body);
      } else {
        res.json(error);
      }
    }
  });
});

module.exports = router;

and see what data this route handler responds with.

like image 26
rishat Avatar answered Oct 25 '22 01:10

rishat


For Laravel users,

First of all install npm i axios package if not.

var axios = require('axios');

var config = {
    /* Your settings here like Accept / Headers etc. */
}

axios.get('http://local.dev/api/v1/users', config)
.then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
});

Hopefully it will help someone!

like image 6
Jaydeep Mor Avatar answered Oct 25 '22 01:10

Jaydeep Mor


In 2022

In node

 const fetch = (...args) => import('node-fetch').then(({default: fetch}) => 
 fetch(...args));

app.get('/checkDobleAPI', async (req, res) => {
try {

const apiResponse = await fetch(
 'https://jsonplaceholder.typicode.com/posts' 
)
const apiResponseJson = await apiResponse.json()

console.log(apiResponseJson)
res.send('Running 🏃')
} catch (err) {
console.log(err)
res.status(500).send('Something went wrong')
}
})
like image 1
Deepak Singh Avatar answered Oct 25 '22 02:10

Deepak Singh