6

I am using Ruby on Rails 3 and I am trying to implement APIs to retrieve account information from a web service. That is, I would like to connect to a web service that has the Account class and get information from the show action routed at the URI http://<site_name>/accounts/1.

At this time, in the web service accounts_controller.rb file I have:

class AccountsController < ApplicationController
  def show
    @account = Account.find(params[:id])

    respond_to do |format|
      format.html
      format.js
      format.json { render :json => @account.to_json }
    end
  end
end

Now I need some advice for connecting to the web service. In the client application, I should have a HTTP GET request, but here is my question: What is "the best" approach to connect to a web service making HTTP requests?

This code in the client application works:

url = URI.parse('http://<site_name>/accounts/1.json')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}

@output = JSON(res.body)["account"]

but, is the above code "the way" to implement APIs?

Is it advisable to use third-party plugins and gems?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
user502052
  • 14,803
  • 30
  • 109
  • 188

6 Answers6

4

Yes, since you're using RESTful routes, they are your basic API. You're also returning structured JSON data easily consumable by an application.

There are other ways to implement a web services API (e.g. SOAP), but this is a good and proper way.

Since it's a web services API, connecting to the correct URL and parsing the response is the way to go on the client side. Though if you need to access many different resources it might be a good idea to create a flexible way of building the request URL.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
3

If you don't need low-level tweak-ability offered by Net::HTTP, instead take a look at using Open-URI, which comes with Ruby. It makes it easy to request a page and receive the body back. Open-URI doesn't have all the bells and whistles but for a lot of what I do it's plenty good.

A simple use looks like:

require 'open-uri'
body = open('http://www.example.com').read

The docs have many other examples.

These are other HTTP clients I like:

They are more tweakable and can handle multiple connections at once if that's what you need. For instance, Typhoeus has a suite of simplified calls, similar to Open-URI's. From the docs:

response = Typhoeus::Request.get("http://www.pauldix.net")
response = Typhoeus::Request.head("http://www.pauldix.net")
response = Typhoeus::Request.put("http://localhost:3000/posts/1", :body => "whoo, a body")
response = Typhoeus::Request.post("http://localhost:3000/posts", :params => {:title => "test post", :content => "this is my test"})
response = Typhoeus::Request.delete("http://localhost:3000/posts/1")

HTTPClient has similar shortened methods too.

mikeryz
  • 527
  • 3
  • 8
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • 1
    open-uri is the way to go for the simple requests. If you need to post etc, take a look at rest-open-uri. – Aaron Hinni Feb 18 '11 at 19:03
  • Can I handle multiple connections using Net::HTTP? – user502052 Feb 18 '11 at 19:09
  • You can, but you'll do a lot more work setting up the threads. See http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html. I'd recommend looking at the Net::HTTP docs to see, then read both HTTPClient and Typhoeus + Hydra and decide. http://stackoverflow.com/questions/4579712/is-it-possible-to-initiate-multiple-parallel-http-requests-using-eventmachine-wit/4579840#4579840 is an example of Typhoeus + Hydra. http://stackoverflow.com/questions/4832956/best-way-to-concurrently-check-urls-for-status-i-e-200-301-404-for-multiple-ur/4833811#4833811 is another. – the Tin Man Feb 18 '11 at 19:19
2

I'd recommend using Rails' ActiveResource for most cases. Failing that, httparty.

idlefingers
  • 31,659
  • 5
  • 82
  • 68
1

I would use ActiveResource if you just need a simple way to pull in rest-based resources. It's already included in rails and pretty trivial to set up. You just specify a base url and resource name in your ActiveResource subclass and then you can CRUD rest-based resources with an interface similar to that of ActiveRecord.

1

rest-client is the most popular gem for easily connecting to RESTful web services

Yarin
  • 173,523
  • 149
  • 402
  • 512
  • It's popular. "Most popular"? I'd need to see proof. – the Tin Man Dec 27 '13 at 04:46
  • That doesn't prove it's the most used, only downloaded a lot. Unless each client "phones home" to an impartial metric-gathering site, or sends unique identification that can be gathered from HTTPd logs, there's no usage metrics, and I know they don't do that. Saying its popular because it's downloaded a lot isn't overly useful; It could be downloaded a lot because they make a incremental updates forcing a lot of `gem update` requests. Numbers, without disclosure of the underlying metrics mean very little. Connections per client library would be a better measure. – the Tin Man Dec 29 '13 at 03:29
  • @theTinMan - So you'd rather use imaginary usage metrics instead of real world download metrics? Good luck with that ;). (And FYI, regarding incremental updates, it actually has *fewer* releases than the next two most downloaded clients.) – Yarin Dec 30 '13 at 16:01
  • Figure out how to include real metrics for OpenURI and it'd be accurate. OpenURI is probably the most used of them all; It's convenient, easy to use and build-upon and built-in. – the Tin Man Dec 30 '13 at 19:41
  • @theTinMan - OpenURI only supports GET requests, so it doesn't qualify as a REST client. (There's a project called rest-open-uri, but it's not as popular) – Yarin Dec 31 '13 at 20:01
  • Since the OP is asking about GET requests, it should be acceptable. – the Tin Man Dec 31 '13 at 21:20
0

I think one of the best solutions out there is the Her gem. It encapsulates restful requests providing objects with active-record like behavior.

McShashi
  • 139
  • 1
  • 5