#<RestClient::NotFound: 404 Not Found> error + rest-client gem - ruby-on-rails

I'm getting the below error for rest-client gem while file uploading. Gem is installed properly.
require 'rest-client'
class SimpleService
include RestClient
// other methods //
def update_request method, opts ={}
headers = set_request_header
payload = opts
url = #base_uri + url_path(method)
begin
# RestClient.put url, payload, headers
RestClient::Request.execute(method: :put, url: url,
payload: payload, headers: headers)
rescue RestClient::ExceptionWithResponse => e
byebug
e.response
end
end
end
parameters for the rest client is
headers is {"Authorization"=>"ApiKey SHctT2tSNE94Ijp0cnVlfQ.4ylSKUJurtqCqfiNcm2vRROyHyWjJxWi0WFLsABLY74", "content_type"=>"json"}
url is "https://sandbox.test-simplexcc.com/v2/users/604776/kyc"
payload is <ActionController::Parameters {"identity_kyc_docunt_1"=>#<ActionDispatch::Http::UploadedFile:0x007fe2183a6d10 #tempfile=#<Tempfile:/var/folders/95/z56d5kd10_sb7s82b982fpjw0000gn/T/RackMultipart20180628-1288-1oncnou.png>, #original_filename="35155-6-adventure-time-picture.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"identity_kyc_docunt_1\"; filename=\"35155-6-adventure-time-picture.png\"\r\nContent-Type: image/png\r\n">, "controller"=>"simplex", "action"=>"update_kyc"} permitted: true>
I'm using the postman client call my rest end points. for every request im getting the same error.
(byebug) e
#<RestClient::NotFound: 404 Not Found>
I tried other rest client gem calls to invoke the endpoints. for everything i'm getting the same error.
Thanks
Ajith

I had to convert the payload to json and it solved the problem.
RestClient::Request.execute(method: :put, url: url,
payload: payload.to_json, headers: headers)

Related

Net/HTTP in rails with request header and body

I am trying to call external API for my project and I have some troubles while using Net::HTTP in my rails lib . Here is my code
class ApiCall
def self.do_api_request(api_token, body)
require 'net/http'
require 'uri'
uri = URI.parse('https://sample.com')
header = {'Token' => api_token, 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
request = Net::HTTP::Post.new(uri.request_uri, header)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == "https")
request.body = body
http.request(request)
end
end
This is how I use it (assume I knew the api_token and body):
body = {'id' => 2, 'age'=> 23};
ApiCall.do_api_request(api_token, body)
This way, it throws an error back:
NoMethodError: undefined method `bytesize' for Hash
Then after check online, seems like the body is hash instead of string, so I did this
body = URI.encode_www_form(body) and after rerun, it gives me :
400 bad request
I have no ideas how to put both header and body into a rails Net::HTTP method
Solution:
I know where the problem is. request body supposed to be string
so body = "{'id' : 2, 'age' : 23}" , I used body.to_json
I will suggest you to use HTTParty for calling an api. This is real simple to use. Following are the examples-
HTTParty.get("https://api.bigcommerce.com/stores/"+#store.store_hash+"/v3/catalog/categories", :headers => #your_header_data)
This will return the response. Also for post request,
HTTParty.post("https://api.bigcommerce.com/stores/"+#store.store_hash+"/v3/catalog/products", :headers => #auth, :body => product_json)
So you can pass body to in body param here.

how to access this kind of hash

I am using RestClient to make a post request and i made it so i an error response back so i can print those error messages in console
i tried the following per the restclient gem documentation
begin
response = RestClient.post base_uri, params.to_json, content_type: 'application/json', accept: 'application/json'
rescue RestClient::ExceptionWithResponse => err
error = err.response
p "this is the error response #{error}"
end
when i print err.response i get the following
"this is the error response {\"error\":{\"message\":\"An active access token must be used to query information about the current us
er.\",\"type\":\"OAuthException\",\"code\":2500,\"fbtrace_id\":\"HTzmJ0CcIfd\"}}"
how do i access the message in the above hash to display it in console?
tried
p "this is the error response #{error.message}"
and it gives me "Bad request" - have no idea where it gets that
If you're just looking to output it:
error = JSON.load(err.response)
puts error['error']['message']
You can always format it a bit better:
puts '[Code %d %s] %s' % [
error['error']['code'],
error['error']['type'],
error['error']['message']
]
Note that using puts inside of a Rails process is not going to work very well. You might want to use Rails.logger.debug instead.
The response you received is in JSON. You'll need to decode the JSON first and then interact with the data. Personally, I like MultiJson for this:
begin
response = RestClient.post base_uri, params.to_json, content_type: 'application/json', accept: 'application/json'
rescue RestClient::ExceptionWithResponse => err
error = MultiJson.load(err.response)
p "this is the error response #{error[:message]}"
end

Rails RestClient POST request failing with "400 Bad Request"

Looking at the docs there aren't any good examples of how to make a POST request. I need to make a POST request with a auth_token parameter and get a response back:
response = RestClient::Request.execute(method: :post,
url: 'http://api.example.com/starthere',
payload: '{"auth_token" : "my_token"}',
headers: {"Content-Type" => "text/plain"}
)
400 bad request error:
RestClient::BadRequest: 400 Bad Request
from /Users/me/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rest-client-1.8.0/lib/restclient/abstract_response.rb:74:in `return!'
from /Users/me/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rest-client-1.8.0/lib/restclient/request.rb:495:in `process_result'
from /Users/me/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rest-client-1.8.0/lib/me/request.rb:421:in `block in transmit'
Any good examples how to make a POST request using RestClient?
EDIT:
This is how I make the request in the model:
def start
response = RestClient::Request.execute(method: :post,
url: 'http://api.example.com/starthere',
payload: '{"auth_token" : "my_token"}',
headers: {"Content-Type" => "text/plain"}
)
puts response
end
Try using a hash like this:
def start
url= 'http://api.example.com/starthere'
params = {auth_token: 'my_token'}.to_json
response = RestClient.post url, params
puts response
end
If you just want to replicate the curl request:
response = RestClient::Request.execute(method: :post, url: 'http://api.example.com/starthere', payload: {"auth_token" => "my_token"})
Both Curl and RestClient defaults to the same content type (application/x-www-form-urlencoded) when posting data the this format.
In case you land here having the same Issue, Just know that this is a common error that happens when your environment variables are not "set".
I put this in quotes because you might have set it but not available in the current terminal session!
You can check if the ENV KEY is available with:
printenv <yourenvkey>
if you get nothing then it means you need to re-add it or just put it in your bash files
FYI: Putting my ENV variables in my ~/.bash_profile fixed it

How to handle RestClient::ServerBrokeConnection

I am using the latest version of rest-client gem and upon external access I see a lots of RestClient::ServerBrokeConnection errors, how should I handle this?
The following call fails
response = RestClient::Request.execute(method: :post, url: url, headers: headers, "Content-Type" => "application/x-www-form-urlencoded")
This error happens when the server broke the connection with the client. You can decide to retry the request or just bubble the error for the user to know about it and handle it.
Because how rest-client handles broken connections as shown here, all you can do is rescue from it
begin
response = RestClient::Request.execute(method: :post, url: url, headers: headers, "Content-Type" => "application/x-www-form-urlencoded")
rescue RestClient::ServerBrokeConnection
// retry or do something
end

What is difference, ruby HTTParty and angular $http

HTTParty
url = "https://my-url/locomotive/api/tokens.json"
response = HTTParty.post(url, body: { :api_key => #api_key })
On the server:
Started POST "/locomotive/api/tokens.json" for 202.4.224.66 at 2014-06-15 17:59:57 +1000
Processing by Locomotive::Api::TokensController#create as JSON
Parameters: {"api_key"=>"5fcfe580e42944c896a49469c30aa97a384b497d"}
$http
$http({
url: 'https://ernie-locomotive.12wbt.com/locomotive/api/tokens.json',
method: 'POST',
params: data
});
Started OPTIONS "/locomotive/api/tokens.json?api_key=5fcfe580e42944c896a49469c30aa97a384b497d" for 59.167.21.65 at 2014-06-15 17:53:43 +1000
Processing by Locomotive::Public::PagesController#show as JSON
Parameters: {"api_key"=>"5fcfe580e42944c896a49469c30aa97a384b497d", "path"=>"locomotive/api/tokens"}
WARNING: Can't verify CSRF token authenticity
Basically, I thought they are two same methods. Seems that $http doesn't pass http method. HTTParty does what it requers and grabs the results correctly.
Because it is cross origin request, browser sends CORS preflight request before actual one...
More about CORS: http://www.html5rocks.com/en/tutorials/cors/

Resources