问题
I am beginner in working with API. I'm trying to work with the Forecast API. I don't want to use its official wrapper, because first I like to study and learn.
class Forecast
include HTTParty
base_uri "api.forecast.io/forecast/#{@api_key}/#{@latitude},#{@longitude}"
def initialize(api_key,latitude,longitude)
self.api_key = api_key
self.latitude = latitude
self.longitude = longitude
end
end
Now what should be the next step after initialization. I've tried to understand using the httparty
gem examples, but cant figure out what exactly to do.
Could you help me to fix it & point related resources with APIs?
回答1:
I do not use httparty gem when working with APIs instead i use typhoeus gem which allow making parallel http requests and therefore enable concurrency but i believe the example below will also work if you use httparty. I am going to use a simple example to show how i work with APIs. Let's say you are trying to communicate with a JSON api service to fetch a list of products.
The url of the service endpoint is http://path/to/products.json
in your application, you can have a products_controller.rb
with an index
action that looks like this:
class ProductsController < ApplicationController
def index
# make a http request to the api to fetch the products in json format
hydra = Typhoeus::Hydra.hydra
get_products = Typhoeus::Request.new('http://path/to/products.json')
get_products.on_complete do |response|
products = MultipleProducts.from_json(response.body)
@products = products.products
end
hydra.queue get_products
hydra.run
end
end
Let's say that the http request to http://path/to/products.json
returns the following json
{"products" [{"id": 1,
"name": "First product",
"description": "Description",
"price": "25.99"}, {"id": 2,
"name": "Second product",
"description": "Description",
"price": "5.99"}]
This json can be wrapped in a class with a name like, multiple_products.rb
Which looks like this:
class MultipleProducts
attr_reader :products
def initialize(attributes)
@products = attributes[:products]
end
def self.from_json(json_string)
parsed = JSON.parse(json_string)
products = parsed['products'].map do |product|
Product.new(product)
end
new(products: products)
end
end
You can then use ActiveModel to create a product model like this:
class Product
include ActiveModel::Serializers::JSON
include ActiveModel::Validations
ATTRIBUTES = [:id, :name, :description, :price]
attr_accessor *ATTRIBUTES
validates_presence_of :id, :name, :price
def initialize(attributes = {})
self.attributes = attributes
end
def attributes
ATTRIBUTES.inject(ActiveSupport::HashWithIndifferentAccess.new) do |result, key|
result[key] = read_attribute_for_validation(key)
result
end
end
def attributes= (attrs)
attrs.each_pair {|k, v| send("#{k}=", v)}
end
def read_attribute_for_validation(key)
send(key)
end
end
In your app/views/products/index.html
, you can have:
<h1>Products Listing</h1>
<ul>
<% @products.each do |product| %>
<li>Name: <%= product.name %> Price: <%= product.price %> </li>
<% end %>
</ul>
This will list all the products fetched from the api. This is just but a simple example and there is much more involved when working with APIs. I would recommend you read Service-Oriented Design with Ruby and Rails for more details.
来源:https://stackoverflow.com/questions/24304831/rails-working-with-api