Friday, June 22, 2012

A gem to create objects from external APIs

I published a gem to load into objects XML and JSON files provided over external APIs (urls). The gem is called api_object and available to be installed over "gem install api_object".

The gem is very easy to use.

  1. subclass your object to be loaded from ActiveApi::ApiObject
    class Station < ActiveApi::ApiObject 
    end 

  2. Specify the url to load the data from, optionally an action and a mode, an api key and parameters(options) for the url; such as the url would look like
    "http://<api_url>/<action>?&key=<api_key>&<parameter1=value1&parameter2=value2...>"

    This will be defined in the top object over the function "initialize_from_api". Options for this function:

    :url - specify url
    
    :action - specify action
    
    :mode - specify mode (such as 'verbose', 'terse' etc.)
    
    :key - api key
    
    :data_tags - specify tag parameters under which object data might be stored, for example <location value='San Francisco'> - "value" would be a data tag. :data_tags accepts a single value or an array. 
    
    :url_options - parameters
    

    The following is designed to generate real time departure estimates for BART stations:

    class Station
    
    initialize_from_api :url => "http://api.bart.gov/api/", :action => 'etd.aspx', :key => 'MW9S-E7SL-26DU-VV8V', :url_options => {:cmd =&gt; 'etd'}
    
    end
    

    In this example, the url generated to get real time departure estimates from the Richmond station will be: http://api.bart.gov/api/etd.aspx?cmd=etd&orig=RICH&key=MW9S-E7SL-26DU-VV8V

  3. Define class attributes and mapping of the attributes to the api where the api name is different. To define api simple type mappings, use "api_column <attribute name>, <api attribute name>". To define api association mapping, use "api_association <association attribute name>, <api attribute name>, :as => <association class name>". Either the second, or the third parameters could be omitted. If the third parameter is omitted, the class name will be the same as the attribute name.

    In the following example, a simple attribute name is "abbreviation", but the name defined in the api XML documents is "abbr". An association is defined in the attribute :est, the api mapping is :etd and it's an object of the class Estimate.

    class Station < ActiveApi::ApiObject 
    
    initialize_from_api :url => "http://api.bart.gov/api/", :action => 'etd.aspx', :key => 'MW9S-E7SL-26DU-VV8V', :url_options => {:cmd => 'etd'}
    
    attr_reader :name, :abbreviation, :date, :time, :est
    
    api_column :abbreviation, :abbr
    api_association :est, :etd, :as => Estimate
    
    end
    

  4. To load api data into an object, use the class method "get_results(options)". In the example, get real time estimates for the station Glen Park.

    data = Station.get_results(:orig => 'GLEN')
    

    Please, note that data loaded might be either a hash, or an array of hashes, depending on the api.

  5. Create an object from the data

    If the example, the data received is a hash, so create an object.

    station = Station.new(data)
    

    If the data is an array of hashes, then it might be used to create an array of objects

    stations = data.map {|d| Station.new(d)}
    

  6. The gem also allows to get location based data by ip. Please, refer to the documentation.

No comments:

Post a Comment