Part 2: local clients pushing data to local server with RESTful web services

It’s really easy! But only when you know how! Like most stuff is. I was completely confused at the beginning. What does RESTful web services mean? It’s just a convention. You access the web services almost as you would access using a browser.

  • /products gives index.html with products
  • /products.xml renders the xml with products
  • /products/1 renders the show.html of product with id 1
  • /products/1.xml returns product with id 1 as xml
  • and so on. That’s RESTful

If you are using rails, you follow its convention of a controller with the methods index, show, new, create, edit, update, destroy.

To post data to a RESTful controller, you perform a POST to mydomain.com/myobjects.xml with a xml file. Using httparty, it’s like this

post('/diagonses.xml', :query => {:diagnose => { :time => time,
                                    :diagnosis => 'RESTfully in love'}}})

Creating a RESTful Web Service Client

OK, I promised to show how I build the dummy clients to feed my app through its web services. I skipped the random code

  1. rails my_dummy_clients
  2. cd my_dummy_clients
  3. sudo gem install httparty #for creating requests
  4. sudo gem install whenever #For creating crontab task by speaking ruby
  5. paste in the file my_client_dummy.rb into app/model/. #Should reside there due to default ‘whenever’ functionality
  6. wheneverize .   # remember the dot .  #creates the schedule file will edit later

config/schedule.rb

should/could look like this:

set :environment, "development"
every :hour do
  runner "MyClientDummy.report_cool_values"
end

app/models/my_client_dummy.rb

require 'httparty'

CONFIG = YAML::load_file(RAILS_ROOT+"/config/settings.yml")[RAILS_ENV]

class MyClientDummy
 include HTTParty

 base_uri "#{CONFIG['server']}:#{CONFIG['port']}"

 #This is used to authenticate as user u!
 def initialize(u, p)
   @auth = {:username => u, :password => p}
 end

 #Just to show how you would perform a GET. Try this before POST, to check
 #that you have the urls correct.
 def self.get_cool_values
   get('/cool_values.xml', :basic_auth => @auth)
 end

 def create_cool_values
   temperature = 50-rand(101) # -50 to 50
   time = current_time_with_zero_minutes_and_seconds
   logger "#{Time.now} Sending cool values with temperature #{temperature}
                       for time #{time}"
   options = {:query => {:cool_value => { :time => time,
                                          :temperature => last_prod}}}
   #remove this if you don't use authentication
   options.merge!({:basic_auth => @auth})
   self.class.post( '/cool_values.xml',  options)
 end

 #Whole hours, quick and dirty
 def current_time_with_zero_minutes_and_seconds
   t = Time.now
   t - (t.min*60+t.sec)
 end

 def self.report_cool_values
   client = MyClientDummy.new('my_client_dummy', 'dummy_pwd')    
   response = client.create_cool_values
   if response.code == 422
     puts "status unprocessable entity (#{response.code}): #{response.body}"
   elsif response.code == 201
     logger "#{Time.now} CREATED code #{response.code}: #{response.body}"
   else
     puts "ERROR, should have gotten response code 201, but
               was #{response.code}. Content: #{response.body}"
   end
 end
end

#my own logger for this simple task.
#puts to the console will be caught by CRON and generate a
#mail (/var/mail/username)
def logger (logtext)
 logfile = "#{RAILS_ROOT}/client.log"
 f = File.open(logfile, 'w')
 f << Time.now.to_s + logtext + "\n"
 f.close
end    

config/settings.yml

development:
 server: 'localhost'
 port: 3000

Running it

Make sure your local app is running at localhost:3000 or whatever you specified in settings.yml

in my_dummy_clients run whenever like this

~/dev/temp/my_dummy_clients $ whenever
PATH=xxxxxxx

@hourly /Users/xxx/dev/temp/my_dummy_clients/script/runner -e development
                                     "MyClientDummy.report_cool_values"

TEST MANUALLY first. Copy the line from after the @hourly and run it. When you are done debugging and swearing, finish it all up by running

whenever -w 
which writes to your crontab. List crontab jobs with
crontab -l

and remove all jobs with

crontab -r

That’s it:) Hope this was of any help! Comments and tips are, as always, greatly appreciated.


About Ole Morten Amundsen

Developer, programmer, entrepreneur. Java, .Net, ruby, rails, agile, lean. Opinionated enthusiast!
This entry was posted in integration, rails, ruby and tagged , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s