1

Trying to figure out the right way to send a RESTful request to an API using the Node.js Needle library. I think everything is right except the code concerning the image URL. No matter how I try to change what it looks like or where I put it, I keep getting an error that says it's an invalid image, but it's not, the URL is fine. So, my guess is my code is wrong and so whatever it thinks is the URL for the image, is probably not the URL (but maybe some other code or code in a location that should be where the body/image URL is).

const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg'

// Request parameters.
const params = {
    returnFaceId: true,
    returnFaceLandmarks: false,
    returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
}

var options = {
    body: '{"url": ' + '"' + imageUrl + '"}',
    headers: {
        'Content-Type': 'application/json',
        'Ocp-Apim-Subscription-Key': subscriptionKey
    }
}

needle.post(endpoint, params, options, function (err, res, body) {
    console.log(`Status: ${res.statusCode}`)
    console.log('Body: ', body)
    console.log('ERROR: ' + err)
    //console.log(res)
})

I have also tried to write the body like a plain ol' object: body = { 'url': imageURL}, but still getting the same error.

Error:

Status: 400
Body:  { error: { code: 'InvalidURL', message: 'Invalid image URL.' } }

Here is the API I am trying to call, which has been confirmed to work with other samples: https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236

Azurespot
  • 3,066
  • 3
  • 45
  • 73

1 Answers1

0

For this request you have a combination of parameters:

  • Some of them as query strings (your 'params')
  • Some of them as a body payload (your options.body)

Therefore, it seems that you cannot use needle.post directly because it can do query string params OR body param but not both at the same time.

So there are several options:

  • Set your query string params in the URL field
  • Change your lib

For the 1st option, here is an example:

const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/3/37/Dagestani_man_and_woman.jpg'

// Request parameters.
const params = {
    returnFaceId: true,
    returnFaceLandmarks: false,
    returnFaceAttributes: 'age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
}

// Adding params to query string
serialize = function(obj) {
    var str = [];
    for (var p in obj)
      if (obj.hasOwnProperty(p)) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
      }
    return str.join("&");
}

endpoint = endpoint + "?" + serialize(params)

// Setting body and options
var body = '{ "url": ' + '"' + imageUrl + '"}'

var options = {
    headers: {
        'Content-Type': 'application/json',
        'Ocp-Apim-Subscription-Key': subscriptionKey
    }
}

needle.post(endpoint, body, options, function (err, res, body) {
    console.log(`Status: ${res.statusCode}`)
    console.log('Body: ', body)
    console.log('ERROR: ' + err)
    //console.log(res)
})
Nicolas R
  • 13,812
  • 2
  • 28
  • 57