RestClient post request in ruby on rails - ruby

RestClient post request
I tried post request couple ways
#user = {name: 'xxxxxx', email: 'xxxxxx#gmail.com', password: 'qwertyqqq'}
RestClient.post 'http://localhost:4123/api/users?token=<token>', #user
RestClient::Request.execute(method: :post, url: 'http://localhost:4123/api/v1/users', token: '<token>', payload: '#user', headers: {"Content-Type" => "application/json"})
Error: RestClient::BadRequest: 400 Bad Request or RestClient::UnprocessableEntity: 422 Unprocessable Entity
Success cases
When i made a get request with rest client and with curl is just fine.
RestClient.get 'http://localhost:4123/api/v1/users?token=<token>'
With curl:
Get request:
curl -X GET http://localhost:4123/api/v1/users/1?token=<token>
Post request for helpy:
curl -d '{"name":"xxxx","email":"xxxx#gmail.com","password":"12345678", "admin": true, "role":"admin"}' -H "Content-Type: application/json" -X POST http://localhost:4123/api/v1/users?token=<token>

The difference between the CURL version and the RestClient version is that in the CURL version you send a JSON string as payload but in the RestClient sends the string '#user'.
It should be fine when you actually send JSON:
RestClient.post(
"http://localhost:4123/api/v1/users?token=<token>",
#user.to_json,
{ content_type: :json, accept: :json }
)

Related

Rest client post with username and password

curl --request POST \
--url https://example.com/token/grant \
--header 'password: password' \
--header 'username: user' \
--data '{"app_key":"my_app_key","app_secret":"my_app_secret"}'
I am trying to get an equivalent ruby code for the above curl request with rest client.
I have tried:
auth = 'Basic ' + Base64.encode64( "#{AA['user_name']}:#{AA['password']}" ).chomp
response = RestClient.post'https://example.com/token/grant', {"app_key":"my_app_key","app_secret":"my_app_secret"}, { 'Authorization' => auth , :accept => :json, 'Content-Type': 'application/json' }
response = JSON.parse(response)
It did not work.
2nd try:
RestClient.post 'https://example.com/token/grant', {"app_key":"my_app_key","app_secret":"my_app_secret"}.to_json, {'username': 'username', 'password': 'password', content_type: 'application/json'}
Also did not work.
I have checked username and password is correct.
It showing that username is missing in the header.
Thanks in advance.
As per the description it seems like when running the request using RestClient the header is action is unable to process the header (username since it is the first key in the header hash).
I have executed the below command on a custom code and it worked.
RestClient.post 'https://example.com/token/grant', {"app_key":"my_app_key","app_secret":"my_app_secret"}.to_json, {username: 'username', password: 'password', content_type: 'application/json'}
Note: I have just updated the representation of header keys passed in the header hash.
I have tried with Rest client. It did not work. Then I also tried Faraday, Net HTTP nothing works.
Then I have tried with curb. It works.
require 'curb'
request_path= 'https://example.com/token/grant'
payload = {
app_key: 'app_key',
app_secret: 'app_secret'
}
http = Curl.post(request_path, payload.to_json) do |http|
http.headers['username'] = 'user_name'
http.headers['password'] = 'password'
http.headers['Content-Type'] = 'application/json'
end
JSON.parse(http.body_str)

Ruby RestClient GET request with payload

Please help me with the following:
I have a number of application and associated records.
app with id 1 has: record1, record2 and record3.
app with id 2 has: record1 ... record1000
To filter out records for app 1 Im using curl. I can get records with the following command:
curl -i -H "accept: application/json" -H "Content-type: application/json" -X GET -d '{ "filters": { "app_id":"1" }}' http://[rails_host]/v1/records?token=[api_token]
How can I do the same but with ruby RestClient (gem 'rest-client' '1.7.2')
To get all records I do the following:
RestClient.get("http://[rails_host]/v1/records?token=[api_token]", { :content_type => 'application/json', :accept => 'application/json'})
The Problem is that app ids are not returned so I cannot parse response and take records that has app id = 1
Any ideas how can I add payload to Restclient.get to filter out records?
You can see in the docs here that the only high level helpers that accept a payload argument are POST, PATCH, and PUT. To make a GET request using a payload you will need to use RestClient::Request.execute
This would look like:
RestClient::Request.execute(
method: :get,
url: "http://[rails_host]/v1/records?token=[api_token]",
payload: '{ "filters": { "app_id":"1" } }',
headers: { content_type: 'application/json', accept: 'application/json'}
)

Sending a POST request with RestClient and Authentication headers

I have the following curl request that I would like to translate into a RestClient API request.
curl -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Authorization: Token user_token="tokenhere", email="email#myemail.com"' -X POST "https://api.myapi.io/reports?start_date=2016-05-10&end_date=2016-05-12" -v
I tried the following as a RestClient POST but I keep getting a 401. When I do the curl request I get a response.
url = "https://api.myapi.io/reports?start_date=2016-05-10&end_date=2016-05-12"
RestClient.post(url, :authorization => 'Token email="email#myemail.com" user_token="tokenhere"', :content_type => 'application/json', :accept => 'application/json')
Any ideas?
The string you're expecting is:
'Token user_token="tokenhere", email="email#myemail.com"'
The line you're sending is:
'Token email="email#myemail.com" user_token="tokenhere"'
The parameters are flipped around. :) If that doesn't work, I'd check and make sure that the curl request is expecting escaped characters. You could be effectively sending this:
"Token email=\"email#myemail.com\" user_token=\"tokenhere\""

Ruby rest-client returning 401 while curl command works

I have a working curl command which returns exactly what I want, bunch of JSON:
curl -D- -u username:password -X GET -H "Content-Type: application/json" https://stash.address.net/rest/api/1.0/projects/FOOBAR/repos\?limit\=1000
And I need to transform it into RestClient::Request, but I am still getting 401 back:
RestClient::Request.execute(
method: :get,
headers: {
content_type: 'application/json'
},
username: 'username',
password: 'password',
url: 'https://stash.address.net/rest/api/1.0/projects/FOOBAR/repos',
params: {
limit: '1000'
},
verify_ssl: false
)
Did I forget something? Is there something missing from my request? Isn't it exactly same as the curl command above?
From the documentation I don't see any mention of the username and params options. They suggest to interpolate the value in the URL.
RestClient.get 'https://username:password#stash.address.net/rest/api/1.0/projects/FOOBAR/repos', { accept: :json, params: { limit: 1000 }}

Rest-Client: how to post multipart/form-data?

I have to implement the curl POST request below listed, in Ruby, using Rest-Client.
I have to:
send params in header;
send params (that do not contain a file) as multipart/form-data:
$ curl -X POST -i -H "Authorization: Bearer 2687787877876666686b213e92aa3ec7e1afeeb560000000001" \
https://api.somewhere.com/endpoint -F sku_id=608399
How can I translate the curl request using the RestClient rubygem?
Reading documentation (multipart paragraph): https://github.com/rest-client/rest-client
I coded as:
#access_token = 2687787877876666686b213e92aa3ec7e1afeeb560000000001
url = 'https://api.somewhere.com/endpoint'
req = { authorization: "Bearer #{#access_token}"}
RestClient.post url, req, {:sku_id => 608399, :multipart => true}
But I get a server error; is the Ruby code above correct?
Thanks a lot,
Giorgio
Since I had trouble understanding the example Dmitry showed, here is an example for creating a Multipart request to upload an image:
response = RestClient.post 'https://yourhost.com/endpoint',
{:u_id => 123, :file => File.new('User/you/D/cat.png', 'rb'), :multipart => true},
{:auth_token => xyz5twblah, :cookies => {'_cookie_session_name' => cookie}}
It's code not valid for RestClient implementation.
headers should follow after payload.
module RestClient
def self.post(url, payload, headers={}, &block)
...
end
end
UPDATE
#access_token should be a string "2687787877876666686b213e92aa3ec7e1afeeb560000000001"
then
RestClient.log = 'stdout'
RestClient.post url, {:sku_id => 608399, :multipart => true}, req
and log
RestClient.post "https://api.somewhere.com/endpoint", "--330686\r\nContent-Disposition: form-data; name=\"sku_id\"\r\n\r\n608399\r\n--330686--\r\n", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate", "Authorization"=>"Bearer 2687787877876666686b213e92aa3ec7e1afeeb560000000001", "Content-Length"=>"79", "Content-Type"=>"multipart/form-data; boundary=330686"

Resources