How to pass payload via JSON file for curl? - json

I can successfully create a place via curl executing the following command:
$ curl -vX POST https://server/api/v1/places.json -d "
auth_token=B8dsbz4HExMskqUa6Qhn& \
place[name]=Fuelstation Central& \
place[city]=Grossbeeren& \
place[address]=Buschweg 1& \
place[latitude]=52.3601& \
place[longitude]=13.3332& \
place[washing]=true& \
place[founded_at_year]=2000& \
place[products][]=diesel& \
place[products][]=benzin \
"
The server returns HTTP/1.1 201 Created.
Now I want to store the payload in a JSON file which looks like this:
// testplace.json
{
"auth_token" : "B8dsbz4HExMskqUa6Qhn",
"name" : "Fuelstation Central",
"city" : "Grossbeeren",
"address" : "Buschweg 1",
"latitude" : 52.3601,
"longitude" : 13.3332,
"washing" : true,
"founded_at_year" : 2000,
"products" : ["diesel","benzin"]
}
So I modify the command to be executed like this:
$ curl -vX POST http://server/api/v1/places.json -d #testplace.json
This fails returning HTTP/1.1 401 Unauthorized. Why?

curl sends POST requests with the default content type of application/x-www-form-urlencoded. If you want to send a JSON request, you will have to specify the correct content type header:
$ curl -vX POST http://server/api/v1/places.json -d #testplace.json \
--header "Content-Type: application/json"
But that will only work if the server accepts json input. The .json at the end of the url may only indicate that the output is json, it doesn't necessarily mean that it also will handle json input. The API documentation should give you a hint on whether it does or not.
The reason you get a 401 and not some other error is probably because the server can't extract the auth_token from your request.

To clarify how to actually specify a file that contains the JSON to post, note that it's with the # sign as shown in the OP
e.g. a typical post to a local .NET Core API:
curl -X POST https://localhost:5001/api -H "Content-Type: application/json" -d #/some/directory/some.json

You can cat the contents of a json file to curl via the --data-raw parameter
curl https://api.com/route -H 'Content-Type: application/json' --data-raw "$(cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//')"
curl https://api.com/route -H 'Content-Type: application/json' -d #<(jq . ~/.json/payload-2022-03-03.json)
curl https://api.com/route -H 'Content-Type: application/json' -d #<(jq '{"payload": .}' < ~/.json/payload-2022-03-03.json)
Note: comments in the json file are filtered out via grep -v '^\s*//'
You can also pass the data to curl via stdin using grep or cat or jq
grep -v '^\s*//' ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d #-
cat ~/.json/payload-2022-03-03.json | grep -v '^\s*//' | curl https://api.com/route -H 'Content-Type: application/json' -d #-
jq . ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d #-
jq '{"payload": .}' < ~/.json/payload-2022-03-03.json | curl https://api.com/route -H 'Content-Type: application/json' -d #-

Related

curl command for REST API which takes json input

I want to call REST API by passing json input.
I have following details-
username
apitoken
apiurl
Jsonfile
I have already tried
curl -d #Metadata.json -H "Content-Type: application/json" <> --user xyz:apitoken --insecure
but i m getting null values for all the parameters in the json file.
What am i doing wrong here?
Simple Solution would be to create a sample postman with above details then follow below steps -
Click on the code icon.
Choose cURL from the drop-down.
There’s your cURL command
Sample curl command -
curl -X POST \
https://something.com/endpoint \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 1f0fcc007739' \
-H 'apikey: CSZftBtR0WaN' \
-H 'cache-control: no-cache' \
-d '{
"Id": "5de675",
"xxxxx": "500081"
}'

Stream the JSON Results of Curl into Data Parameter of Curl

I'm trying to stream the JSON output from one curl into the data parameter of another curl. Possible?
Step 1: For example the curl that outputs the JSON is:
curl -sG api.com/test -H "Authorization: Bearer ${token}" | jq '.[] | select(.query|test("latency")) | #json'
Returning:
"{\"query\":\"origin == 'router' and name == 'latency'\",\"threshold\":{\"critical\":65000,\"warning\":55000,\"type\":\"UPPER\"}}"
Step 2: If I use the output of the first curl in the second curl I have a successful response:
curl -v "api.com/test" --data "{\"query\":\"origin == 'router' and name == 'latency'\",\"threshold\":{\"critical\":20000,\"warning\":15000,\"type\":\"UPPER\"}}" -H "Authorization: Bearer ${token}" -H "Content-Type: application/json"
Successful response:
{
"query" : "origin == 'router' and name == 'latency'",
"threshold" : {
"critical" : 20000.0,
"type" : "UPPER",
"warning" : 15000.0
}
}
Step 1 and 2 Combined: I'm trying to combine both steps into one like so:
curl -sG hapi.com/test -H "Authorization: Bearer ${token}" | jq '.[] | select(.query|test("latency")) | #json' | curl -d #- -H "Authorization: Bearer ${token}" -H "Content-Type: application/json" "api.com/test"
But keep getting a bad request:
{
"timestamp" : 1553950852034,
"status" : 400,
"error" : "Bad Request",
"exception" : "org.springframework.http.converter.HttpMessageNotReadableException",
"message" : "Bad Request",
"path" : "/test"
}
Possible?
The quotes you see in your output from the first command are literal quotes, added by #json. They differ from the quotes you use in the second example, which are just syntactic quotes to protect the contents from shell expansion.
When piping directly from the first curl to the second, the syntactic quotes aren't necessary, since the shell never sees the data. You need to remove the #json filter which is wrapping your response in quotes.
auth="Authorization: Bearer ${token}"
curl -sG hapi.com/test -H "$auth" |
jq '.[] | select(.query|test("latency"))' |
curl -d #- -H "$auth" -H "Content-Type: application/json" "api.com/test"
You can try
curl -v "api.com/test" --data "`curl -v -sG api.com/test -H "Authorization: Bearer ${token}" | jq '.[] | select(.query|test("latency")) | #json'`"

OPENIDM- HTTP PUT cURL request

I'm new to openIDM, I'm trying to execute the following query, getting proper results as expected which is POST.
$ curl -k -s https://localhost/openidm/managed/zzzz?_action=create -H 'Content-Type: application/json' -H 'X-OpenIDM-Username: '"openidm-admin"'' -H 'X-OpenIDM-Password: '"openidm-admin"'' -H 'Accept: application/json' -d
'{ "x": "'"AA1"'", "xx": "'"xx"'", "xxx": "'"xxx"'","xxxx": "'"xxxx"'"}'
Results:
{"_id":"db0489f6-d390-481f-8708-0970b3e42469","_rev":"0","x":"AA1","xx":"xx","xxx":"xxx","xxxx":"xxxx"}
But I want to have id value to be created as client Assigned ID not the one generated by openidm, and for that I am using PUT command as below
$ curl -k -s PUT https://xxxx/openidm/managed/zzzz/AA1 -H 'Content-Type: application/json' -H 'X-OpenIDM-Username: '"openidm-admin"'' -H 'X-OpenIDM-Password: '"openidm-admin"'' -H 'Accept: application/json' -d '{ "x": "'"AA1"'", "xx": "'"xx"'", "xxx": "'"xxx"'","xxxx": "'"xxxx"'"}'
Result :
{"code":400,"reason":"Bad Request","message":"The resource instance
/managed/zzzz/AA1 cannot be created"}
Output what I want is
{"_id":"AA1","_rev":"0","x":"AA1","xx":"xx","xxx":"xxx","xxxx":"xxxx"}
I am not sure what I'm doing wrong, Any suggestion ? I followed openidm documentation and below is the link for that.
https://backstage.forgerock.com/docs/idm/5.5/integrators-guide/#about-crest-create

Extract token from a curl request and use in another shell command

I've started picking up bash scripting and I'm stuck at something I'm trying to wrap my head around.
I have a curl command that outputs a token and I need to use it in the following command:
curl -k 'https://server:port/session' -X POST -H 'Content-Type: application/json' -d '{"username":"admin","password":"password"}'
It then outputs a token here:
{"token":"ac07098ad59ca6f3fccea0e2a2f6cb080df55c9a52fc9d65"}
I then need to use it in the follow up command
curl https://server:port/ -k -X POST -H 'Content-Type: application/json' -H 'X-Cookie:token=token' -d '
I was thinking I could output the token to a file, then have a sed command write the token to a file, then the new command use a variable where token=$token
Thanks!
This is where a JSON parsing tool comes in handy (such as jq):
$ echo '{"token":"ac07098ad59ca6f3fccea0e2a2f6cb080df55c9a52fc9d65"}' | jq -r .token
ac07098ad59ca6f3fccea0e2a2f6cb080df55c9a52fc9d65
So
json=$( curl -k 'https://server:port/session' -X POST -H 'Content-Type: application/json' -d '{"username":"admin","password":"password"}' )
token=$( jq -r ".token" <<<"$json" )
curl https://server:port/ -k -X POST -H "X-Cookie:token=$token" ...
With no further tool than a bash (tested Centos/Rhel7/GitBash) :
json=$(curl -k 'https://server:port/session' \
-X POST -H 'Content-Type: application/json' \
-d '{"username":"admin","password":"password"}') \
&& token=$(echo $json | sed "s/{.*\"token\":\"\([^\"]*\).*}/\1/g") \
&& echo "token = $token"
then use your authentication needing commands like that :
curl https://server:port/ -k -X POST \
-H 'Content-Type: application/json' \
-H 'X-Cookie:token=$token' -d ...'
If Python is installed, and hopefully it is on modern systems, you can do something like:
OUTPUT="$(curl -k 'https://server:port/session' -X POST -H 'Content-Type: application/json' -d '{"username":"admin","password":"password"}' | python -c "import sys, json; print json.load(sys.stdin)['token']")"
This will give you:
echo $OUTPUT
ec2e99a1d294fd4bc0a04da852ecbdeed3b55671c08cc09f
Use the `` syntax:
cmd1result=$(command1 | cut -d ':' -f 2 | grep -Po "[a-z0-9-]+")
command2 $cmd1result

Parse.com - How to upload a JSON file using the REST API

I am trying to upload a JSON file using Parse's REST API with no success so far.
The request I am trying to make is the following:
curl -X POST \
-H "X-Parse-Application-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "X-Parse-REST-API-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "name" : "myName" }' \
https://api.parse.com/1/files/test.json
The reponse is as follows:
{"code":1,"error":"internal error"}
I believe my request is correct, the JSON is valid, my Application ID and REST API Key are also correct.
To top it off, I can successfully upload an invalid JSON. For example, the same request with an invalid JSON:
curl -X POST \
-H "X-Parse-Application-Id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "X-Parse-REST-API-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '#{ "name" : "myName" }' \
https://api.parse.com/1/files/test.json
Returns a correct reponse JSON:
{
"url":"http://files.parsetfss.com/e88af32e-2e48-400b-aa1c-2f167f3d2785/tfss-550782bd-718c-46b1-bac1-9e366f957d7a-test.json",
"name":"tfss-550782bd-718c-46b1-bac1-9e366f957d7a-test.json"
}
Has anyone had similar problems, or could anyone point me what I am doing wrong?
[]'s!