How can I correctly turn a list() into a JSON object for a body response?

Hello RStudio Community :wave:, I have a question regarding JSON body responses on R using the httr package (specifically the PATCH()).

Objective

The idea is to update (or patch :wink: ) a JSON object in an API. To achieve this, I will use PATCH(). Using PATCH(), I have to send the necessary information to the API server. The API requires the body of my response to be of type JSON. The problem here is to replicate the JSON correctly.

Code Samples

The JSON I need to send has to look like this:

{
  "data":  {"someData":  012345}
}

The R code that I use to replicate this JSON is:

toJSON( list(`data`= list(`someData`=012345)) )

But, when I use the toJSON() I get the following:

{"data":{"someData":[12345]}} 

The Problem

The problem here is in the [12345], I don't want that data to be inside an array. My response has to be like the first code sample.

I will appreciate any help I can get.

My full PATCH() code, just in case:

PATCH(
     url = "https://apidomain.example/apidir/example",
     config = add_headers(
         Authorization = paste("Auth Type",  "API KEY example")
       ),
    body = toJSON(list(`data`= list(`someData`=012345)))
)

I get a 400 error: bad request :frowning_face:

I make GPX files sometimes to load into GPS units. Similar formatting requirements. I end up just pasting the corect format like so:

body = paste("{",
             paste('"data": {"someData":  012345}'),
             "}",
             collapse = "\n")

This would replace the entire line:

  body = toJSON(list(`data`= list(`someData`=012345)))
1 Like

So if I don't need to replace with variables, then that paste() should not be included ?

Cool! The statement I suggested evaluates to exactly the response that you said you needed, but only if it is evaluated. Apparently being wrapped inside the PATCH() prevented that, so something extra would be needed to force evaluation. The solution you found looks like the right one.

I'm curious, does

body = cat("{",
      '"data": {"someData":  012345}',
      "}",
      collapse = "\n")

work?

1 Like

The paste() here is optional, works the same either way.

I will let you know if that works :+1:t2::innocent:.

Sadly no, I get the following:

$statusCode
[1] 400

$error
[1] "Bad Request"

$message
[1] "Payload validation error: 'Expected type object but found type null'."

$errorCode
[1] "invalid_body"

The code:

PATCH(
     url = "https://apiexample.com/endpointexample",
     config = add_headers(
         Authorization = paste("API KEY TYPE",  "API_KEY")
     ),
     content_type_json(),
     body = cat("{",
                '"data": {"someData":  012345}',
                "}",
            collapse = "\n")
)

Then again, maybe I am doing something wrong; who knows :laughing:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.

I included the paste() in the middle because I assume you will be replacing the text with variables.

1 Like

Hey, the result of your reply lead me to the solution. While the use of paste() didn't worked (still got the 400 error) its return value (which is "{ \"app_metadata\": {\"tier\": \"basic\"} }" ) got me thinking: "Maybe the API server is not aware that my response is of type JSON".

httr has a content_type_json() function. This is used to specify that your body response is of type JSON.

So I made the following edit to my code:

PATCH(
     url = "https://apidomain.example/apidir/example",
     config = add_headers(
         Authorization = paste("Auth Type",  "API KEY example")
       ),
    content_type_json(), # <---- THE FIX
    body = toJSON(list(`data`= list(`someData`=012345)))
)

Another option for the body is to type the JSON directly like this (which I did):

body = '{ "data":  {"someData":  012345} }'

So thank you so much for the reply ! :sunglasses::muscle:

1 Like