Consuming REST API from Rails Application
I'm building my first Rails App and I want it to consume everything from a REST API. What I want to do is to have Rails serve my web application as a frontend to my开发者_开发百科 API. As far as I've read (I'm staring with Rails right now), Rails has a lot of potential with ORMs and direct access to database systems. My platform, on the other hand, is designed in such a way that every layer is accessed via a defined interface (in this case a REST API), so no databases are read from any client, but via their interfaces.
For example, my API exposes the following resource:
https://api.example.com/v1/users/feature-xxx [GET]
And I want my web app to have a page like:
https://example.com/feature
So the users will visit this URL and when logged in, the Rails app will request the data to generate this dynamic content from my API.
The question is:
- What are the necessary steps for my Rails Application to consume its data from a HTTP/Rest Backend? and,
- Is this a good design for a Rails app?
Thanks!
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.
I would highly recommend ActiveResource for your requirement. My experience with it has been really good. Provided that the API you intend to consume is really REST, I don't think there is any cleaner design for consuming data through REST API. From it's README,
Active Resource
Active Resource (ARes) connects business objects and Representational State Transfer (REST) web services. It implements object-relational mapping for REST web services to provide transparent proxying capabilities between a client (ActiveResource) and a RESTful service (which is provided by Simply RESTful routing in ActionController::Resources).
Philosophy
Active Resource attempts to provide a coherent wrapper object-relational mapping for REST web services. It follows the same philosophy as Active Record, in that one of its prime aims is to reduce the amount of code needed to map to these resources. This is made possible by relying on a number of code- and protocol-based conventions that make it easy for Active Resource to infer complex relations and structures. These conventions are outlined in detail in the documentation for ActiveResource::Base.
Overview
Model classes are mapped to remote REST resources by Active Resource much the same way Active Record maps model classes to database tables. When a request is made to a remote resource, a REST XML request is generated, transmitted, and the result received and serialized into a usable Ruby object.
Configuration and Usage
Putting Active Resource to use is very similar to Active Record. It’s as simple as creating a model class that inherits from ActiveResource::Base and providing a site class variable to it:
class Person < ActiveResource::Base self.site = "http://api.people.com:3000/" end
Now the Person class is REST enabled and can invoke REST services very similarly to how Active Record invokes life cycle methods that operate against a persistent store.
# Find a person with id = 1 ryan = Person.find(1) Person.exists?(1) # => true
As you can see, the methods are quite similar to Active Record’s methods for dealing with database records. But rather than dealing directly with a database record, you’re dealing with HTTP resources (which may or may not be database records).
Read more here...
If you decide to not use an HTTP client library like Farady or HTTParty, you can use open-uri to grab the data from the endpoint that you need and parse it with JSON.
Requirements: open-uri and json
In the controller:
@people = JSON.parse(open("http://api.people.com:3000/people").read, symbolize_names: true)
In the view:
<% @people.each do |person| %>
Name:<%= person[:name] %>
Age:<%= person[:age] %>
<% end %>
Yes it can be a good design.
My advice it to read "Service Oriented Design with Ruby And Rails: http://www.amazon.com/Service-Oriented-Design-Rails-Addison-Wesley-Professional/dp/0321659368
It focus on Restful Ruby apps just like your example with an emphasis on scaling and performance. It also investigates different frameworks (Rack, Sinatra, Rails) and the roles they fill well.
Unfortunately I have not implemented this strategy my self (yet!) so I can not give you any first hand advice.
精彩评论