Why does Invoke-RestMethod reject my JSON request body?

0
0
Asked By MellowPine47 On

I'm converting a curl request to PowerShell's Invoke-RestMethod for an API endpoint that expects a JSON array of objects. The curl request sends an array like [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}]. I first created a here-string containing one JSON object and then piped it through ConvertTo-Json before passing it as the request body, but the API returned an invalid_json error. What is the correct way to construct and send this body, especially when submitting only one object?

3 Answers

Answered By NeonCedar5 On

The request body should look like this for two entries: $body = @'
[
{ "key1": "value1", "key2": "value2" },
{ "key1": "value3", "key2": "value4" }
]
'@. A single-quoted here-string is convenient because the JSON double quotes don’t need escaping. The important parts are not double-converting an already valid JSON string and including the array brackets required by the endpoint.

Answered By BrightOwl63 On

A more maintainable approach is to create PowerShell hashtables and convert the resulting array to JSON. Be careful to preserve the array shape when there is only one item: $body = ConvertTo-Json -InputObject @(@{ key1 = 'value1'; key2 = 'value2' }) -Depth 3. For multiple items: $body = @(@{ key1 = 'value1'; key2 = 'value2' }, @{ key1 = 'value3'; key2 = 'value4' }) | ConvertTo-Json -Depth 3. Then use Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -ContentType 'application/json' -Body $body.

SilverMaple19 -

PowerShell can enumerate a one-element array through the pipeline, which can turn it into a JSON object instead of a JSON array. Supplying it with -InputObject helps retain the outer array.

Answered By QuietHarbor8 On

The here-string already contains JSON, so don’t pipe it through ConvertTo-Json again. Also, the curl example sends an array, not a single object. Even with one item, the API may require the surrounding square brackets: $body = @'
[
{
"key1": "value1",
"key2": "value1"
}
]
'@. Then send it with Invoke-RestMethod and set ContentType to application/json.

CobaltFern22 -

That was the key issue in my case: the endpoint required [{...}] even when there was only one object. Using a literal JSON array fixed the request.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.