How to get both response JSON and headers with Got?

1.1k Views Asked by At

I'm using Got to make requests to a Strapi API from Node, like so:

res.setHeader('Content-Type', 'application/json')
try {
  const request = req.query.request
  const decodedRequest = Buffer.from(request, 'base64').toString()
  const api = process.env.API_URL ? process.env.API_URL.replace(/\/$/, '') : ''

  const url = `${api}${decodedRequest}`

  const response = await got.get(url)
  const body = await got.get(url).json()
  const headers = JSON.parse(JSON.stringify(response.headers))

  res.status(200).json({
    headers: headers,
    data: body
  })
} catch (e) {
  res.status(500).json({})
}

This works but note that I have the request twice because if I do:

res.setHeader('Content-Type', 'application/json')
try {
  const request = req.query.request
  const decodedRequest = Buffer.from(request, 'base64').toString()
  const api = process.env.API_URL ? process.env.API_URL.replace(/\/$/, '') : ''

  const url = `${api}${decodedRequest}`

  const response = await got.get(url)
  const body = response.json()
  const headers = JSON.parse(JSON.stringify(response.headers))

  res.status(200).json({
    headers: headers,
    data: body
  })
} catch (e) {
  res.status(500).json({
    error: e
  })
}

it Just crashes and the e from the catch returns an empty error so I have no idea what's going on

I need the headers because the pagination info from Strapi is returned there:

enter image description here

1

There are 1 best solutions below

3
jonrsharpe On BEST ANSWER

This works because of the value you're awaiting. The conventional example:

const body = await got.get("...").json();

is equivalent to:

const res = got.get("...");
const body = await res.json();
          // ^ note

but not:

const res = await got.get("...");
         // ^ note
const body = res.json();

From the Promise API docs:

The main Got function returns a Promise.

Although in order to support cancelation, PCancelable is used instead of pure Promise.

The json method is attached to this PCancelable object, not the value it resolves to. If you try to call it on the response, therefore, you get TypeError: res.json is not a function.

What you want is something like:

const res = await got.get("...");
const body = JSON.parse(res.body);
const headers = res.headers;
// ...

That said, if you're doing this for pagination reasons you could also look into their API for that.