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
Tagged: api, call API, external API, parse API, RESTfull, Ruby
