Monday 12 June 2017

Render raw image bytes to response body

I'm creating an API that creates authorized API calls to Google's APIs, specifically Drive for this question. My API is working fine and uses Google's Node API to make the requests. When I fire off a request to this resource, I get back the following response:

{
 "kind": "drive#file",
 "id": "...",
 "name": "bookmobile.jpg",
 "mimeType": "image/jpeg"
}

I use the above response to determine the MIME type of the file I'm to display later. I then make a subsequent call to the same endpoint, but specifying alt=media as an option to download the file as specified in Google's Guide. If I console.log or res.send() the response, I get the following output:

image bytes

Which we can see is the raw image bytes from the API call. How do I render these bytes to the response body properly? My code is as follows:

// DriveController.show
exports.show = async ({ query, params }, res) => {
  if (query.alt && query.alt.toLowerCase().trim() === 'media') {
    // Set to JSON as we need to get the content type of the resource
    query.alt = 'json'

    // Get the Files Resource object
    const options = createOptions(query, params.fileId)
    const filesResource = await Promise.fromCallback(cb => files.get(options, cb))

    // Grab the raw image bytes
    query.alt = 'media'
    await createAPIRequest(createOptions(query, params.fileId), 'get', res, filesResource)
  } else {
    await createAPIRequest(createOptions(query, params.fileId), 'get', res)
  }
}

async function createAPIRequest (options, method, res, filesResource = {}) {
  try {
    const response = await Promise.fromCallback(cb => files[method](options, cb))
    if (filesResource.hasOwnProperty('mimeType')) {
      // Render file resource to body here
    } else {
      res.json(response)
    }
  } catch (error) {
    res.json(error)
  }
}

Searching through various answers here all seem to point to the following:

res.type(filesResource.mimeType)
const image = Buffer.from(response, 'binary')
fs.createReadStream(image).pipe(res)

But this kills my Express app with the following error:

Error: Path must be a string without null bytes

How would I go about rendering those raw image bytes to the response body properly?



via Francisco Mateo

No comments:

Post a Comment