Home > Software design >  How do I successfully search and API using a POST request in R?
How do I successfully search and API using a POST request in R?

Time:05-25

I have been trying to set up a search in the https://explorer.natureserve.org/api-docs/ API, however, I keep getting the following error:

"JSON parse error: Cannot deserialize value of type `java.lang.Integer` from Object value (token `JsonToken.START_OBJECT`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.Integer` from Object value (token `JsonToken.START_OBJECT`)"

I am not sure where the issue is, as I have very similar code in Python, but the search works fine there.

Here is my code:

search_text = '{
"criteriaType" : "species",
"textCriteria" : [{"paramType" : "textSearch", "searchToken" : "Acanthomintha ilicifolia", "matchAgainst" : "allScientificNames", "operator" : "similarTo"}],
"statusCriteria" : [ ],
"locationCriteria" : [ ],
"pagingOptions" : {"page" : null, "recordsPerPage" : null},
"recordSubtypeCriteria" : [ ],
"modifiedSince" : null,
"locationOptions" : null,
"classificationOptions" : null,
"speciesTaxonomyCriteria" : [ ]}'

search_json = fromJSON(search_text)

searchResults = POST("https://explorer.natureserve.org/api/data/speciesSearch", body=search_json, encode="json")

contentACIL_raw = content(searchResults)

CodePudding user response:

It can be very messy decoding/re-encoding JSON data. It would be much better just to store the data in R as a list, then let the POST command take care of encoding to JSON. For example

search_data = list(
  criteriaType= "species",  
  textCriteria= list(list(paramType = "textSearch", searchToken = "Acanthomintha ilicifolia", matchAgainst = "allScientificNames", operator = "similarTo")),
  statusCriteria= character(),
  locationCriteria= character(),
  pagingOptions= list(page = NA, recordsPerPage = NA),
  recordSubtypeCriteria = NA,
  modifiedSince = NA,
  locationOptions = NA,
  classificationOptions = NA,
  speciesTaxonomyCriteria = character()
)

searchResults = httr::POST("https://explorer.natureserve.org/api/data/speciesSearch", body=search_data, encode="json")
httr::content(searchResults)

Note I had to change "quickSearch" to "textSearch" because "matchAgainst" didn't seem to be a valid option for "quickSearch".

You can preview the encoded JSON format with

jsonlite::toJSON(search_data, auto_unbox=TRUE)
# {"criteriaType":"species","textCriteria":[{"paramType":"textSearch",
# "searchToken":"Acanthomintha ilicifolia","matchAgainst":"allScientificNames",
# "operator":"similarTo"}],"statusCriteria":[],"locationCriteria":[],
# "pagingOptions":{"page":null,"recordsPerPage":null},"recordSubtypeCriteria":null,
# "modifiedSince":null,"locationOptions":null,"classificationOptions":null,
# "speciesTaxonomyCriteria":[]} 
  • Related