Tutorial: How to get data from external API ? PART 2: Sending Request, Parsing Output [Ruby, JSON, REST]


Here we are with Part 2 of our tutorial. Who missed the first part – it’s here. Also if you missed it please take a look at the Github Movies-CLI app, which I am taking my examples from.

In this part we will discuss two things:

1. Making HTTP request to the API Path
2. Parsing response

I know your time is precious so lets start.

 Making HTTP request to the API Path

By this time you should already have all  your  API configurations loaded into @config of RottenTomatoes::API class, if they are not please check out Part 1 .

To send request to the third party API (RottenTomatoes in our case) we will need to use a gem. I am using  RestClient gem. (Note: You can if you want use net/http built in Ruby functionality, but I find RestClient easier to use).

In regards to gem installation – of course you can manually install gem but I prefer to use a Gemfile.

After installing you will need to require RestClient with:


require 'restclient'

Now all we need to do is put together our configuration into a URL, that RestClient will call.

I am doing this within a separate method:

# Constructs base url used for API calls from api_paths configuraiton file
#
# @return [String] base url
  def base_url
	if @config.has_key?('rottentomatoes')
	  @config['rottentomatoes']['protocol'] + @config['rottentomatoes']['host'] + @config['rottentomatoes']['api_path']
	else
	  raise StandardError, 'api_paths.yml must have rottentomatoes information such as host, protocol and api_path'
	 end
  end

This method is pretty straightforward. It can be enhanced to check if @config has every part of the URL,or you can even create ‘initializer’ that won’t even go to this method if @config is not fully populated with information, but for the purpose of this tutorial I left it straightforward.

So we check if there is ‘rottentomatoes’ key in the @config, and if there is we build URL, otherwise we raise an exception.

Now lets go to the part where we call this URL:

# Receives String, makes call to RottenTomatoes and returns JSON object with movies information from RottenTomatoes
#
# @param [String] title movie title to get more info about
#
# @return [HashMap] JSON with movie information
def get_movie_by_title(title)
# using RestClient make call to restful API with api_ley title and max_movies_per_output
  RestClient.get(base_url,
    {:params =>
      {
        :apikey => @config['rottentomatoes']['api_key'],
        :q => title,
        :page_limit => @config['rottentomatoes']['max_movies_per_output']
      }
  # act on response result
   }) { |response, request, result, &block|
      case response.code
      # if success connection start acting on result
	when 200
	  json_result = JSON.parse(response.body)
	  if json_result.has_key?('movies')
	    put_json_into_movie_obj(json_result['movies'])
	  end
      # if not succesfull just raise an exception
	else
	  raise StandardError, "Cannot connect to RottenTomatoes API, please check config/api_paths.yml for valid api_key"
	end
  }
end

The sole purpose of this method is to call the RottenTomatoes API based on the ‘title’ passed to this method. I am using RestClient.get because current API path expects GET Http request. I am using base_url that we seen earlier and 3 parameters, two of which are taken from the @config and one supplied by user.

So my URL looks the same the an example we seen in RottenTomatoes docs :

 http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=Toy+Story+3&page_limit=1

Parsing response

After sending request via RestClient, I am checking response.code, if it is not 200 which means successful with body, I am raising an exceptions, otherwise I use built in Ruby JSON functionality to parse JSON object I receive back and call my own function

 put_json_into_movie_obj(json_result['movies'])

to put information from JSON into my custom class RottenTomatoes::Movie .

Note: JSON.parse allows to transform response.body which is string into a JSON string which allows access to different its parts (HashMap).

Last Part of this equation is:


private

  # Puts JSON object into a RottenTomatoes::Movie object
  # @param [HashMap] movie_json JSON object with movie information
  #
  # @return [Array] array of RottenTomatoes::Movie objects
  def put_json_into_movie_obj(movie_json)
    movie_json.map { |movie| RottenTomatoes::Movie.new(movie['id'], movie['year'], movie['gernes'],																												 
                                                       movie['title'], movie['release_dates'], movie['ratings'],																											
                                                       movie['synopsis'], movie['posters'], movie['abridged_cast'],																												  
                                                       movie['runtime']) }
  end

This piece of code is super straightforward, what it does it maps and saves different parts of JSON into RottenTomatoes::Movie .

After this we have our RottenTomatoes::Movie, populated with information from RottenTomatoes API, and we can do anything we want with it!

Pretty straightforward right ?

In the next tutorial I will show you how to prettify your command line output and show your movie information.

If you can’t wait just:

1. pull movie-cli app
2. rename config file from ‘.sample’ to ‘.yml’
3. put your api_key’ into config
4. in movie-cli do bundle update
5. run ruby movie_info.rb ‘Unbroken’

That’s it. You want to call another API ? Create new entry into config, get your API Key, modify RottenTomatoes::API class to parse information you want – and you are good to go.

If you have any questions regarding this, put it in the comments or shoot me an email!

Thanks for reading!

Anatoly

Advertisements

About Anatoly Spektor

My name is Anatoly Spektor (originally Anatolijs Spektors) I am Software and Web Developer. I have worked in Seneca Center for Development of Open Technology on Big Blue Button Add-on - Polling Module, Red Hat and some other places :) I am an author of the book 'Eclipse Debugging How To', Muay Thai fighter and amateur photographer ;)
This entry was posted in open-source, 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