How do I use Sinatra to access the Google+ API?
20/Sep 2011
How do I use Sinatra to access the Google+ API?
RubyLearning is conducting many free, online courses on Google+. Some participants wanted an answer to their question “How do I use Sinatra to access the Google+ API?” This blog post explains the same. Read on.
Pre-requisite
Install Sinatra, Git, Heroku, Bundler
Refer RubyLearning’s article on Google+.
Create a folder on your hard disk
Create a folder sinatragplus
. This is where we will store our Sinatra app. Open a Bash shell in this folder.
Create the following folders also
Organize your application
Static Files
Static files are served from the public
folder. Note that the public
folder name will not be included in the URL. A file ./public/stylesheets/style.css is made available as rubylearning.org/stylesheets/style.css. Do note that we can have any directory layout under the public
folder.
Layout
We will soon create layout.erb
file in the views
folder. This allows the basic layout of our site headers, footers and navigation panes to be controlled independently. A change in layout.erb
is instantly applied across our whole site.
Let’s look at a sample file:
<html> <head>..</head> <body> <%= yield %> </body> </html>
In the above file, note the usage of yield
. The file calls yield
at the point you want the content to be included i.e. it refers to some .erb in the views
folder and the results of that .erb are stuck at the place, where you called yield
.
Now, let’s write our app’s layout.erb
file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>A Sinatra app to access Google+</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="description" content="RubyLearning.org" /> <meta name="keywords" content="rubylearning,ruby,ruby programming,ruby course,sinatra course" /> <link rel="stylesheet" type="text/css" href="/stylesheets/style.css" /> <link rel="icon" type="image/ico" href="/images/favicon.ico" /> </head> <body> <%= yield %> </body> </html>
Image
I am using a favicon (favicon.ico) for my app, which is stored in the public/images
folder.
Stylesheet
We have our stylesheet namely style.css
in the folder public/stylesheets
.
body { line-height: 1.6em; } h1 { color: #2A1959; border-bottom: 2px solid #2A1959; } h2 { color: #474B94; font-size: 1.2 em; } #footer { clear: both; border-top: 1px solid #2A1959; text-align: left; height: 50px; font-size: 70%; width: 100%; } #hor-minimalist-a { font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; font-size: 12px; background: #fff; margin: 45px; width: 480px; border-collapse: collapse; text-align: left; } #hor-minimalist-a th { font-size: 14px; font-weight: normal; color: #039; padding: 10px 8px; border-bottom: 2px solid #6678b1; } #hor-minimalist-a td { color: #669; padding: 9px 8px 0px 8px; } #hor-minimalist-a tbody tr:hover td { color: #009; }
View
A view is responsible for generating a user interface, normally based on data. For example, an online store will have a list of products to be displayed on a catalogue screen. The view accesses the data and formats it for the end-user.
All file-based views are looked up in the views
folder.
Using ERB
ERB is written in pure Ruby and is included with the standard Sinatra distribution. ERB allows you to embed Ruby statements in an HTML page.
The important things to know about an .erb
file is that <%= ruby_code %>
evaluates the ruby code and outputs the result, and <% ruby_code %>
evaluates the code, but doesn’t output anything.
We will use ERB for our app.
Note: If we write:
get '/' do erb :index end
This tells Sinatra that when a GET
request for ‘/’ comes in, that we should use the ERB helper to render the index.erb
template, which is stored in the views
sub-folder by convention and marked up with embedded Ruby (ERB).
Write the sinatragplus.rb app
Store sinatragplus.rb
in the folder sinatragplus
:
# sinatragplus.rb require 'sinatra' require 'google_plus' error do erb :'500' end #class class GPlus def initialize(apikey, gid) @apikey = apikey @gid = gid get_info end attr_reader :row0, :row1, :row2 private #Get info about specific G+ ID def get_info # GooglePlus.api_key = 'Your API Key' begin GooglePlus.api_key = @apikey person = GooglePlus::Person.get(@gid.to_i) @row0 = person.display_name @row1 = person.tagline @row2 = person.url rescue Exception => msg # display the system generated error message puts msg end end end get '/' do erb :index end # Display Google+ details post '/show' do @gplus = GPlus.new(params[:apikey], params[:gid]) erb :show end
Explanation
-
Install:
gem install google_plus
. - We are going to use the above installed google_plus gem.
- To access the Google+ API, get your own Google API key.
- Note down the Google+ ID of the person whose Google+ profile you want to display using this app. For example, here’s my Google+ URL and the number in the URL namely 107809992818057105754 is my Google+ ID.
-
When a GET request for ‘/’ comes in, we are going to render the
index.erb
template in thepublic/views
folder. -
The file index.erb has a HTML form that accepts the Google+ API key and ID for the user profile that you want to display. Note that even if you do not give any value to these fields, the app will not crash. Handler is the generic term that Sinatra uses for the “controllers”. A handler is the initial point of entry for new HTTP requests into your application. In handlers you can reach submitted form parameters directly via the
params
hash. Also note, that when you click on the submit button of the form aPOST
request is being sent. -
The
post '/show' do
creates an object of our classGPlus
passing to theinitialize
method the apikey and google id that your entered on the screen (viaparams
). Theinitialize
method in-turn calls a private methodget_info
that accesses the Google+ API and returns a person object We call the methoddisplay_name
,tagline
andurl
on theperson
object and populate instance variables@row0
,@row1
and@row2
. - The show.erb displays these values in a HTML table.
Error Handling
When someone comes to a page on your domain that is no longer there (either because it’s been deleted, because they’ve typed something in wrong or because the link that they followed was wrong) they are shown the dreaded 404 ‘page not found’ error page.
This error simply means that the person was able to communicate with your server but that the server couldn’t find the page that they were after.
404 errors should not be confused with “server not found” or similar errors, in which a connection to the destination server could not be made at all.
When a Sinatra::NotFound
exception is raised, or the response’s status code is 404, the not_found
handler is invoked:
Write 404.erb in the public/views
folder. Note that I had to surround the erb :'404'
in single quotes. This is because Ruby syntax doesn’t let symbol’s first character be a number. By quoting it, it gets around that issue.
A 500 error page will be thrown to the client when the Web server (running the Web Site) encounters an unexpected condition that prevents it from fulfilling the request by the client (e.g. your Web browser) for access to the requested URL.
By default error will catch Sinatra::ServerError
. Sinatra will pass you the error via the ‘sinatra.error’ in request.env
.
Write 500.erb in the public/views
folder.
Our app is ready! Let’s deploy it to Heroku.
Create config.ru file in the folder sinatragplus
This file contains:
require './sinatragplus' run Sinatra::Application
Install required gems for our app
In the Bash shell type:
$ bundle init
Edit the created Gemfile
with your preferred text editor to let it look like this:
source "http://rubygems.org" gem 'sinatra' gem 'google_plus'
In the Bash shell type:
$ bundle check
Finally in the open Bash shell, type:
$ bundle install
Create a Procfile
Use a Procfile
, a text file in the root directory of your application, to explicitly declare what command should be executed to start a web dyno. In this case, you simply need to execute the sinatragplus.rb using Ruby.
Here’s our Procfile
:
web: bundle exec ruby sinatragplus.rb -p $PORT
Setup your local app to use Git
I have the sinatragplus.rb
, Procfile
and config.ru
files already in the folder sinatragplus
.
In the already open Bash shell, type:
$ git init $ git add . $ git commit -m "sinatragplus first commit"
Create the app on Heroku
In the bash shell, type:
$ heroku create sinatragplus
Push your application to Heroku
$ git push heroku master
That’s it, the app is now running on Heroku! You can take a look at it, in your browser type: http://sinatragplus.herokuapp.com/.
What next?
On the person
object use the attributes
method to get all the person
fields back as a Hash:
properties = person.attributes properties.each { |key, value| puts "#{key} equals #{value}" }
Exercise
In show.erb
I have populated only the display_name
, tagline
and url
fields of person
. Populate all the other person
fields in the HTML table that is generated by show.erb
.
Have fun!
Do post a link to your version of this program. Feel free to ask questions and give feedback in the comments section of this post. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning email me at satish [at] rubylearning.org