Search code examples
javascriptexpressmernnode-fetchexpress-router

How to use fetch from node-fetch inside an express router get request


I'm using node-fetch to get external resources from github (user repos) inside an express router get request as follows.

import fetch from 'node-fetch

router.get('/github/:username', async (req, res) => {
  try {
    const uri = `http://api.github.com/users/${req.params.username}/repos?per_page=5&sort=created:asc&client_id=${process.env.GITHUB_CLIENT_ID}&client_secret=${process.env.GITHUB_CLIENT_SECRET}`;

    const response = await fetch(uri, {
      method: 'GET',
      mode: 'cors',
      headers: { 'Content-Type': 'application/json' }
    });

    return res.json(response);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('server error');
  }
});

But I get the following response in postman when I hit this route:

{
    "size": 0,
    "timeout": 0
}

Does anyone know what I'm doing wrong?

EDIT:

If I console.log(response) from fetch, I get (searching for repos from github user, rmosolgo, for example:

Response {
  size: 0,
  timeout: 0,
  [Symbol(Body internals)]: {
    body: Gunzip {
      _writeState: [Uint32Array],
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 5,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: true,
      bytesWritten: 0,
      _handle: [Zlib],
      _outBuffer: <Buffer 5b 7b 22 69 64 22 3a 33 37 33 31 38 30 35 32 32 2c 22 6e 6f 64 65 5f 69 64 22 3a 22 4d 44 45 77 4f 6c 4a 6c 63 47 39 7a 61 58 52 76 63 6e 6b 7a 4e 7a ... 16334 more bytes>,
      _outOffset: 0,
      _chunkSize: 16384,
      _defaultFlushFlag: 2,
      _finishFlushFlag: 2,
      _defaultFullFlushFlag: 3,
      _info: undefined,
      _maxOutputLength: 4294967295,
      _level: -1,
      _strategy: 0,
      [Symbol(kCapture)]: false,
      [Symbol(kTransformState)]: [Object],
      [Symbol(kError)]: null
    },
    disturbed: false,
    error: null
  },
  [Symbol(Response internals)]: {
    url: 'https://api.github.com/users/rmosolgo/repos?per_page=5&sort=created:asc&client_id=Iv1.cafc8d8f7e1b91ac&client_secret=824bedd0eb406f92a3380d8043c273655cdc1f99',
    status: 200,
    statusText: 'OK',
    headers: Headers { [Symbol(map)]: [Object: null prototype] },
    counter: 1
  }
}


Solution

  • If you want to get/extract the JSON from the response, you need to execute async json() on the response. res.json will automatically do this for you. This is similar to fetch in the browser:

    const response = await fetch(uri, {
      method: 'GET',
      mode: 'cors',
      headers: { 'Content-Type': 'application/json' }
    }).then(res => res.json());
    
    return res.json(response);
    

    or:

    const response = await fetch(uri, {
      method: 'GET',
      mode: 'cors',
      headers: { 'Content-Type': 'application/json' }
    })
    
    const data = await response.json();
    
    return res.json(data);
    

    Hopefully that helps!