Using Rails to Consume Web Services/Apis

Using rails to consume web services/apis

I'm working on an app like this right now, so let me offer a few thoughts.

First, if you're a complete newcomer to Rails, then as a first step I'd suggest taking a parallel approach to the problem, with two tracks:

  1. Learn about Rails
  2. Learn about how to interact with an API (make requests and parse responses) in Ruby

These are two separate problems, and although you may end up implementing them together, it's best to think about them in isolation first.

For the first one, I'd suggest writing a couple simple apps first to get a feel for how things work. Even only a simple app will require a certain amount of user interaction, possibly saving records to the DB, etc., problems that are separate from consuming data from an API. There are an endless number of tutorials out there on Rails, but just to mention one, you might try Michael Harti's Learn Web Development with Rails as a starting point.

The second point, consuming API data, is distinct from the problems of designing the app itself. To learn more about this aspect of the problem, I'd suggest using a popular API client gem like (as you mentioned) HTTParty, which I use myself. Rather than immediately try to use the HTTParty methods in a Rails app, as an exercise I'd suggest playing around a bit in a console (irb). If you install the gem (gem install httparty) you can then require it (require 'httparty') from the console and immediately make requests and parse responses from the APIs.

E.g.:

irb(main):001:0> require 'httparty'
=> true
irb(main):002:0> response = HTTParty.get('http://twitter.com/statuses/public_timeline.json')
=> ...

Once you've got a bit more familiar with Rails and with accessing an API in ruby, then you could move on to actually building the app itself. Depending on how complex your requests to the API(s) are going to be, you have a few options as to how to structure your API requests in your Rails app:

  1. Make the requests part of the Rails app itself, directly from controller actions. This is really only okay if you are only going to support a very limited number of request types (e.g. simple search) on a limited number of services. Anything more complex and your controller will get fat, which is a no-no in MVC frameworks.
  2. Create a separate ruby class (usually called an API wrapper) to group together methods for making requests and parsing responses from the API. With a gem like HTTParty you can do this just by adding a line include HTTParty in the class, which adds the module to the class. There are lots of examples out there on how to do this, here is one.
  3. Use a dedicated gem for accessing specific APIs, or create one (or more) yourself. There are gems for most popular services, e.g. Twitter, Linkedin, Flickr, etc. See this list of API client gems for more. This takes away a lot of the pain of interacting with an API, but will only work for a subset of all services.

You mention you're thinking of using HTTParty, which I can recommend as I am using it myself. There are alternatives such as Faraday (see this list of HTTP clients for more), but I find for most tasks HTTParty will do fine. The documentation may be a bit sparse, but there are a bunch of examples that you can work from.

Hope that helps!

Getting started consuming web services in a Ruby on Rails 3 application

I'm a pretty big fan of HTTParty.

It's an abstraction layer on top of Net::HTTP with a nice little DSL for consuming web services. Here's a good example of how easy it is to use.

It's not without some warts (lots of dependencies) but it's really the way to go if you're on the consuming side.

What is the proper Rails Way to consume a RESTful web service on another domain?

There is a plugin/gem called HTTParty that I've used for several projects.

http://johnnunemaker.com/httparty/

HTTParty lets you easily consume any web service and parses results into a hash for you. Then you can use the hash itself or instantiate one or more model instances with the results. I've done it both ways.

For the twitter example, your code would look like this:

class Twitter
include HTTParty
base_uri 'twitter.com'

def initialize(u, p)
@auth = {:username => u, :password => p}
end

# which can be :friends, :user or :public
# options[:query] can be things like since, since_id, count, etc.
def timeline(which=:friends, options={})
options.merge!({:basic_auth => @auth})
self.class.get("/statuses/#{which}_timeline.json", options)
end

def post(text)
options = { :query => {:status => text}, :basic_auth => @auth }
self.class.post('/statuses/update.json', options)
end
end

# usage examples.
twitter = Twitter.new('username', 'password')
twitter.post("It's an HTTParty and everyone is invited!")
twitter.timeline(:friends, :query => {:since_id => 868482746})
twitter.timeline(:friends, :query => 'since_id=868482746')

As a last point, you could use your code above also, but definitely include the code in a model as opposed to a controller.

Consuming REST API from Rails Application

ActiveResource is no longer being included in Rails 4.0. Word is that it is barely maintained these days, and is difficult to customize for REST API endpoints that are not formulated according to the "Rails way".

After some research, I am heavily favoring using Faraday. It includes support for utilizing different HTTP request adapters. It can use EventMachine directly, or libraries like Typhoeus for when you decide to get concurrent. It also supports Rack-like middleware for seamlessly including, say, authentication.

For a REST ORM in Rails that is easily configurable, the relatively new (about a year old) Her looks very promising, and utilizes Faraday.

Update

I completely <3 RestClient. So simple. If you need ORM-style functionality, then you'll need a higher-level abstraction, but for simply consuming an API, you can't beat its simplicity. It just does exactly what it's supposed to do without fuss, has sensible defaults, and has the ability to set advanced options such as auth headers.

how to create web service Api in rails 4?

Actionwebservice is long deprecated, in favour of REST API's. At my previous job we used a fork of actionwebservice in a rails 3 project.

Since there is no maintainer anymore for the actionwebservice gem, that fork never got merged back. If you check the fork history, a lot of people are fixing and partially updating it, but it is scattered all over the place.

Afaik none of the forks were updated to use rails 4. But using a rails 3 fork might just work.

If you really need to build a SOAP API server with Rails, imho your best option is to take a look at Wash-out, but you will have to re-write your API code.

Ruby on Rails API and web services

The REST API generated by Rails can be consume by any client, if you want to use pure HTML and CSS withouth the .erb files (for me brings many advantages when developing) you can access to the Rails API data by AJAX.

I let you the following tutorial:

http://blog.project-sierra.de/archives/1788

Hope it helps

Simplest way to consume Rails REST API

You can use rest-client gem to make your calls easier (though simple net/http would work just as well)

RestClient.post("https://api.teamsnap.com/v2/teams", 
'{"team": {"team_name": "West Nile Mosquitos", "sport_id": 1, "timezone": "Mountain Time (US & Canada)", "country": "United States", "zipcode": 80302}}',
content_type: :json, x_teamsnap_token: my_token)

Connecting to web services using Rails (HTTP requests)?

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.

Ruby on rails without models - if data CRUD is performed by webservices API

Take a look at ActiveResource.

You'll end up with models, but most will only take up one line.

Say your api service has a url like: http://api.fart.com/products.json which spits out a list of products. In your rails app that will be consuming this data, create a Product model inheriting from ActiveResource. First, set your api url for activeresource.

class ActiveResource::Base
self.site = "http://api.fart.com"
end

Next, define a Product class.

class Product < ActiveResource::Base; end

Now, in your controllers, you can do:

Product.all

And it should hit "http://api.fart.com/products.json" and return the good stuff.

Obviously this is a quickly contrived example, but I have recently used it for a similar situation and it worked great.

///////////////

see example applications for basic concept.

///////////////

Per your questions and your pull requests on github I understand what you are trying to do now. ActiveResource does not come with a where method - however, it's find method has an options argument that supports a params hash.

Rails controller with query params

def index
@products = Product.find :all, params: { country: "Brazil", price: 500 }
end

This will hit our Sinatra route at api.fart.com/products.json?country=Brazil&price=500

# Assume we are using ActiveRecord/DataMapper or the like
get "/products.json" do
@products = Product.where country: params[:country], price: params[:price].to_i
json products: @products
end


Related Topics



Leave a reply



Submit