Posting xml to a rest api in rails - ruby-on-rails

I need to post some xml info to a restful api can anyone give me a clue of how to do this? I'm using rails.

In rails, using ActiveResource, you do it like this:
class PersonResource < ActiveResource::Base
self.site = "http://api.people.com:3000/"
self.proxy = "http://user:password#proxy.people.com:8080"
end
ryan = Person.new(:first => 'Ryan', :last => 'Daigle')
# the next line posts this object serialized to xml to the configured url
ryan.save # => true
http://api.rubyonrails.org/classes/ActiveResource/Base.html
If the site you are posting to has a custom API (not active resource) you must use Net:HTTP

Related

Ruby on Rails client app and api app

I have a Ruby on Rails application that serves as an API to other web apps. This API has a controller named AcademicTitlesController, in this controller i have a method active_academic_titles.
class AcademicTitlesController < ApplicationController
def index
....
end
def active_academic_titles
#active_academic_titles = AcademicTitle.where(:academic_unit_id => params[:academic_unit_id]).order('name')
end
end
this method renders a rabl view.
On my routes file i have this
get 'active_academic_titles' => 'academic_titles#active_academic_titles'
Now on the client web application i want to display the json format text(rabl) with html and erb.
On the client web app i have i model
class Api < ActiveResource::Base
MODE = 'dev' # api or dev
self.site = 'http://localhost:3003/'
self.format = :json
end
This model makes the connection to the API, and each model in the client app inheris from this Api model.
My question is this, what do i need or add to my client app so that i can get the data from the api view?
I am not what your goal is, but to my understanding the controller will render the view unless otherwise specified. So if you want it to act as an API just return in JSON form from the server for example add render :json => somedata
You can make changes in Api class as
class Api < ActiveResource::Base
MODE = 'dev' # api or dev
self.site = 'http://localhost:3003/'
self.element_name = "" # You can also use self.collection_name = "" instead
self.format = :json
end
And to access json from get 'active_academic_titles' => 'academic_titles#active_academic_titles'
You need to write
Api.get('active_academic_titles')
Note: Make sure that server port is 3003 and server sends json if at endpoint http://localhost:3003/active_academic_titles.json
Extra Info:
This would not be the most effective way to use of ActiveResource. Generally we should use class name of class inheriting from ActiveResource i.e 'Api' in your case, to be same as endpoint i.e AcademicTitle and also should avoid using self.element_name = "" and instead create a endpoint as http://localhost:3003/academic_titles/active_academic_titles.json
Reference link:
http://api.rubyonrails.org/v3.2.6/classes/ActiveResource/Base.html

Very Basic Rails 4.1 API Call using HTTParty

Relatively new to Rails. I am trying to call an API and it's supposed to return a unique URL to me. I have HTTParty bundled on my app. I have created a UniqueNumber controller and I have read through several HTTParty guides as far as what I want but maybe I'm just a bit lost and really have no idea what to do.
Basically, all I need to do is call the API, get the URL it returns, then insert that URL into the database for a user. Can anyone point me in the right direction or share some code with me?
Let's assume the API is in a JSON format and returns the data like so:
{"url": "http://example.com/unique-url"}
To keep things tidy and well structured, the API logic should belong in it's own class:
# lib/url_api.rb
require 'httparty'
class UrlApi
API_URL = 'http://example.com/create'
def unique_url
response = HTTParty.get(API_URL)
# TODO more error checking (500 error, etc)
json = JSON.parse(response.body)
json['url']
end
end
Then call that class in the controller:
require 'url_api'
class UniqueNumberController < ApplicationController
def create
api = UrlApi.new()
url = api.unique_url
#user = # Code to retrieve User
#user.update_attribute :url, url
# etc
end
end
Basically HTTParty returns a response object that contains the HTTP response data which includes both the headers and the actual content (.body). The body contains a string of data that you can process as you like. In this case, we're parsing the string as JSON into a Ruby hash. If you need to customise the HTTP request to the API you can see all the options in the HTTParty documentation.

Sinatra with Rails reset session every request

I have a rails web application and I need to create API for mobile clients. I choose a Sinatra web framework for this. But I have a problem with my Sinatra app, after every request all data session lost.
My API looks like this(lib/api/core.rb):
module Api
class Core < Sinatra::Base
set :session_secret, 'secret'
enable :sessions
get '/foo' do
content_type :json
session['foo'] = 'some value'
end
get '/bar' do
content_type :json
session['foo']#everytime is nil
end
end
end
In my route.rb I wrote this:
constraints :subdomain => 'api' do
mount Api::Core => '/'
end
I use Rails 3.2.8, Sinatra 1.3.3
And my questions is how can I store data between requests(it's need me for authentication) ?
Your APIs should be stateless. Authentication is usually done with tokens that are sent along with every request. See RailsCast #352 Securing an API for more info.

ruby on rails route params in controller

routes.rb:
match 'first/#!/:name' => 'first#first'
first_controller.rb:
class FirstController < ApplicationController
def first
#name = params[:name]
end
end
But the #name variable is nil when I render the url: http://localhost:3000/first/#!/sayuj
Please help
Anything after the first # in the URL is not (usually) sent back to the server; it's used on client side only.
So the URL http://localhost:3000/first/#!/sayuj in the client will actually call the URL http://localhost:3000/first/ on server side.
See the following posts for more info:
http://code.google.com/web/ajaxcrawling/docs/getting-started.html
http://www.webmonkey.com/2011/02/gawker-learns-the-hard-way-why-hash-bang-urls-are-evil/
http://dannythorpe.com/2011/02/09/side-effects-of-hash-bang-urls/
http://rc3.org/2011/02/09/hash-bang-urls-and-overuse-of-ajax/
Jits is correct that the # in the url will drop the rest of the url, also, I believe your route is incorrect, it should look like:
match 'first/:name', :to => 'first#first'
documentation is at Engine yard rails 3 routes.

How do you log the URL ActiveResource uses?

Rails ActiveResource is awesome ... except for one thing: as far as I can tell, there is no way to see what URL it is using behind the scenes. For instance, let's say I have an ActiveResource called Issue, for a webservice at myIssues.com/issues.xml. If I do:
Issue.find(:all, :params => {:page => 2})
I would expect that ActiveResource would make a call to:
myIssues.com/issues.xml?page=2
... but I don't actually know that. For all I know, ActiveResource could have decided it doesn't like the word "page", so it's actually using:
myIssues.com/issues.xml?mod_page=2
This makes debugging difficult. Right now I've got a situation where, if I go to the URL I think ActiveResource is using, it works just fine. However, when I actually use ActiveResource, it doesn't work. Seeing the URL it's GETing would be immensely helpful in this, so ...
Does anyone know a way to log (or otherwise output; if there's some resource.url method that would work great too) the URL(s) that ActiveResource uses to do its thing?
If you add the following line to your environment.rb file, it will at least log the requests so you know that URLs ActiveResource is hitting:
ActiveResource::Base.logger = ActiveRecord::Base.logger
I'm still searching for a better solution that shows me the response and the data posted to update calls, but at least this is a step in the right direction. I'm really not sure why ActiveResource has a separate logger to start with, but that's another matter.
I just ran into this same exact issue, and came across this post as I was looking for answers. What I did find, that proved useful, is the collection_path method on ActiveResource::Base. So for example, let's say you have the following resource:
class UserPost < ActiveResource::Base
self.site = "http://someApp.com/user/:user_id"
self.element_name = "post"
If you go to the rails console, here are some examples of the output:
>> UserPost.collection_path
"/user//post"
>> UserPost.collection_path(:user_id => 5)
"/user/5/post
This should provide you with exactly what you need to determine how ActiveResource is translating your request into a URL.
To get detail login for ActiveResource have to patch the request method inside the gem(method.
place bellow files inside config/initializers you will get http method, path, request body, request hedaers
response body and header is already there if you need. doc
config/initializers/activeresource_patch.rb
module ActiveResource
class Connection
private
def request(method, path, *arguments)
result = ActiveSupport::Notifications.instrument("request.active_resource") do |payload|
payload[:method] = method
payload[:request_uri] = "#{site.scheme}://#{site.host}:#{site.port}#{path}"
payload[:request_path] = path
payload[:request_body] = arguments[0]
payload[:request_headers] = arguments[1]
payload[:result] = http.send(method, path, *arguments)
end
handle_response(result)
rescue Timeout::Error => e
raise TimeoutError.new(e.message)
rescue OpenSSL::SSL::SSLError => e
raise SSLError.new(e.message)
end
end
end
config/initializers/activeresource_logger.rb
Rails.application.configure do
def activeresource_logger
#activeresource_logger ||= Logger.new("#{Rails.root}/log/activeresource_logger.log")
end
ActiveSupport::Notifications.subscribe('request.active_resource') do |name, start, finish, id, payload|
if Rails.env.development?
activeresource_logger.info("====================== #{start} : #{payload[:method].upcase} ======================")
activeresource_logger.info("PATH: #{payload[:request_path]}")
activeresource_logger.info("BODY: #{payload[:request_body]}")
activeresource_logger.info("HEADERS: #{payload[:request_headers]}")
# activeresource_logger.info("STATUS_CODE: #{payload[:result].code}")
# activeresource_logger.info("RESPONSE_BODY: #{payload[:result].body}")
end
end
end

Resources