Home > front end >  Pass Associative Array as Data Param in POST request using cURL
Pass Associative Array as Data Param in POST request using cURL

Time:11-09

I have an associative array that I want to pass to cURL as POST data. However i have tried multiple things, still it doesn't work.

The array:

declare -A details
details[name]="Honey"
details[class]="10"
details[section]="A"
details[subject]="maths"

The cURL commands have tried so far (all of these failed):

resp = $(cURL --request POST --data details "https://somedomain.net/getMarks")
resp = $(cURL --request POST --data variables=details "https://somedomain.net/getMarks")
resp = $(cURL --request POST --data "variables=$details" "https://somedomain.net/getMarks") 
resp = $(cURL --request POST --data "variables=${details}" "https://somedomain.net/getMarks") 
resp = $(cURL --request POST --data $details "https://somedomain.net/getMarks") 
resp = $(cURL --request POST --data ${details} "https://somedomain.net/getMarks") 
resp = $(cURL --request POST --data variables=details "https://somedomain.net/getMarks")   

Something like shown below, I want the above request to be (indirectly), however I want to pass the array directly instead of writing its contents.

resp = $(cURL --request POST --data '{"variables":[{"name": "Honey"},{"class": "10"},{"section": "A"},{"subject": "maths"}]}' "https://somedomain.net/getMarks")

Please note that to begin with I will always have the associative array ONLY (not any json array or string).

This question rose when I was trying calling cURL command with the associative array as on this link (GITLAB API)(the example does not contain variables array example). Here they have mentioned a variables array (array of hashes).

CodePudding user response:

Assumptions/understandings:

  • no need to list the array entries in any particular order
  • neither the array indices or values contain newlines

One bash idea:

# use a function to build the --data component

build_data() {
    local -n _arr="$1"                       # use nameref so we can pass in the name of any associative array
    local    _sep=""
    local    _string='{"variables":['
    local    _i

    for i in "${!_arr[@]}"
    do
        _string="${_string}${_sep}{\"${i}\": \"${_arr[$i]}\"}"
        _sep=","
    done

    printf "%s]}" "${_string}"
}

Adding this to the curl call:

resp=$(cURL --request POST --data "$(build_data details)" "https://somedomain.net/getMarks")

NOTES:

  • no spaces allowed on either side of the =, ie, resp = $(curl ...) needs to be resp=$(curl ...)
  • without an actual/valid URL I'm guessing a bit on if/where the escaped quotes belong so may need to tweak the escaped quotes to get working correcly

CodePudding user response:

  1. Since I had to use an older version of bash, which does not involve the name referencing as stated on the answer, I had to try to code string creation of the associative array without passing it to a function
  2. Since I always had an associative array to begin with, the process of passing the array as accepted by the gitlab API normally was:
resp=$(cURL --request POST --data '{"variables":[{"name": "Honey"},{"class": "10"},{"section": "A"},{"subject": "maths"}]}' "https://somedomain.net/getMarks")

OR

resp=$(cURL --request POST --data "variables[name]=Honey" --data "variables[class]=10" --data "variables[section]=A" --data "variables[subject]=maths" "https://somedomain.net/getMarks")

So tried some tweaks on the second way and what worked for me was:

_sep=""
_string=""

for index in "${!details[@]}"
do
    _string="${_string}${_sep}variables[${index}]="${details[$index]}"
    _sep="&"
done

resp=$(cURL --request POST --data "$_string" "https://somedomain.net/getMarks")

#which indirectly was:
resp=$(cURL --request POST --data "variables[name]=Honey&variables[class]=10&variables[section]=A&variables[subject]=maths" "https://somedomain.net/getMarks")

And it was a success. Thanks to @markp-fuso for giving me an intuition of creating a string with his logic above.

  • Related