Subscribe to The New and Improved Ruby Codes        RSS Feed

What's a WebAPI anyway? How can I use one? Are https get requests easy in ruby?

Icon Leave Comment
::What is a WebAPI anyway?
So let's say you're programming a desktop app and you'd like to get some information from a twitter account (yes you are that egotistical that you truly believe everyone using your app will want to know the last place you were, and what you were feeling at that moment).

So, the old school way of doing this was called scraping and botting (spidering?) to pull the information off the web. That method was complicated and broke whenever the layout of the website was changed. Then they invented webAPIs. Now you can use a simple API to get that information instead of having to bother with scraping it the hard way.

Oh, incase the term API is foreign to you, the most popular API in the world is the win32 API I believe... With it, you could say... launch a message box to the screen with just one line of code (amazing how rapidly technological achievements can become available to the coding community).

::How to use WebAPIs
WebAPIs are unbelievably simple. To use them, you simply send a get request to the server hosting a WebAPI (they'll tell you) and the server sends you back a string as a response. Think of the response string as just the result of running a function/method with a return value. You can literally simulate this using a web browser right now --with no code involved what so ever! Browse to and the server will respond with json data (you're browser will be all like, "Save this to a file?").

GitHub has a WebAPI. It doesn't really matter what GitHub is for the purposes of this tutorial, but if you are curious, it's a free place where you can store your code and it even has a powerful and fast version control system (well... it is a version control system, I mean).

Now, we're going to do two things with GitHub. First, we're going to pull up a user (me!). Then we're going to upload two strings of text "A key title and an actual key" and tell the server to store those strings as a "GitHub Public Key". We could do anything, but this is what we're choosing to do. Now let's get started.

Authenticate with GitHub API

First, a glance at the API documentation...


Getting User Information:

You can then get extended information on users by their username. The url format is:

/user/show/:username [GET]

so the following command

$ curl
  "user": {
    "gravatar_id": "b8dbb1987e8e5318584865f880036796",
    "company": "GitHub",
    "name": "Chris Wanstrath",
    "created_at": "2007/10/19 22:24:19 -0700",
    "location": "San Francisco, CA",
    "public_repo_count": 98,
    "public_gist_count": 270,
    "blog": "",
    "following_count": 196,
    "id": 2,
    "type": "User",
    "permission": null,
    "followers_count": 1692,
    "login": "defunkt",
    "email": ""

If you authenticated as that user, you will also get this information:

  total_private_repo_count: 1
  collaborators: 3
  disk_usage: 50384
  owned_private_repo_count: 1
  private_gist_count: 0
    name: mega
    collaborators: 60
    space: 20971520
    private_repos: 125


Notice that the curl command curl is the goto way of demonstrating 'get' and 'post' requests to UNIX users. And that's what you use to work with WebAPIs. It's interesting to note that when you boil the internet down, you're left with just a bunch of get and post requests. There is nothing else. There are no files, and there are no server. IP addresses are arbitrary. Just a mess of gets and posts.

First, some code to authenticate with GitHub. Although most people believe the hype about SSL protection is just a poorly thought out NSA marketing scheme, GitHub encourages the use of https and SSL and we must use it. This is a slight complication, but the ruby code remains fairly simple.

http://www.ensta-par...s/Net/HTTP.html Needed this due to lack of documentation

  #require "net/http"
  require 'net/https'    # we'll need this since we're using ssl
  server = ''
  path = '/users/TheNotary'
  username = 'thenotary'                # consider changing me
  password = 'MyPassword'               # me too
  http =,443)       # A)  Net::HTTP
  http.use_ssl = true

  req =               # B)  Net::HTTP::Get
  req.basic_auth username, password

  response = http.request(req)           # C)  Net::HTTP

  r = response.body
  p r

You can run the above code right in irb and look at what it returns. It looks much like a hash => "{\"message\":\"Bad credentials\"}" but in fact, it is a json string. Before we convert it to an actual hash, let's go over some of that SSL code in detail. It's telling you bad credentials cause you've entered the wrong password. You can either create your own user and do further testing with that account, or continue guessing my password until you get it right.

A) Net::HTTP

  http =,443)

Here we're creating a new 'Net::HTTP' object. Allow me to highlight it's coolest properties.

   http.address        # We put our server address here
   http.port           # We put 443 here, the port for SSL
   use_ssl             # We set this to true to tell ruby to actually encrypt our data with...
                       #  SSL rather than just send it plain text to the https port

C) Net::HTTP Continued...

Basically, you can use these objects to send 'post' and 'get' requests (in addition to puts and deletes too I'm sure but never mind that for now). Once you've created a suitable request object, you can use the Net::HTTP object to fire off the request to your targeted server...

   response = http.request(req)           # C)  Net::HTTP

B) Net::HTTP::Get

  req =               # B)  Net::HTTP::Get
  req.basic_auth username, password

There are 4 different request types in the "restful resource" model: Get, post, put, and delete. In ruby, each one get's it's own object. Get's is called "Net::HTTP::Get". Allow me to go over it's articles of interest.

   path               # we set this to the path to the WebAPI method, it's "controller", "method" and "parameter" if you will
   basic_auth         # This is a method which can be used to setup the username password to access the webpage requested

It's pretty straight forward. Once you have it setup, just fire it off using a Net::HTTP object and you'll get a response back from the server.

Add a new ssh key to GitHub

The first step was to make it work on the command line. This took me hours to do because githubs documentation was incorrect/ changed between versions!

$ curl -u 'thenotary:MyPass' -d '{"title":"fromcurl", "key":"rsablabla"}'

That got me a result that I liked at least. Otherwise it was telling me {"message":"not found"} or something. The '-d' stands for data btw.

(Adjust username and password and paste into irb)
def install_key(username, password, rsa_key)
  require 'net/https'
  require 'json'
  server = ''
  path = '/user/keys'

  http =, 443)   # 443 for ssl
  http.use_ssl = true
  req =
  req.basic_auth username, password
  req.body = "{\"title\":\"fromruby\", \"key\":\"#{rsa_key}\"}"
  response = http.start {|http| http.request(req) }
  return_hash = http.request(req).body
  my_hash = JSON.parse(return_hash)
  p my_hash
  the_code = my_hash["errors"][0]["code"]
  if my_hash.key?("errors")   # this doesn't work due to it being a buggy API atm
    return true  # false
  return true


rsa_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCpxktnx2k7aYkxLnvLq8ZeUI8d/d00MeV32na3GZ35qKtJ3Vmvzvb8anF1eZD8/+BtBgYer9/3E0KUi3YNYCeejkdUPj3/Z+aV7Ft0+IeKdzFSqfnfN9UsuS/zkeyia2bjgQJYqk2ZbkMuVIn79UI5ypJWGOXNfKyQ2adYJD7Pjgsxvx8qEXHlU+SszidkwYFEFwT7rZtSXILylmcwCnZryy91cs50vGWxKzKrOV/2iMd8V4Qv7RbhKtQ7OCd19CaZ08H3xqcG1U2lqXIgxSN75bLL71AM0KfIvNOzvigBZnYyb/RKiUQUhA0FnnIYc/7hF9rOe/S1acRiOF6ihz1x"

result = install_key("TheNotary", "MyPassword", rsa_key)

Ok, after much trial and error, and a little packet sniffing, I got things to work. The WebAPI always returns the same error, even when the call was effective. That's pretty lame, but there's a way to check that it worked. I'll leave that to your imaginations though.

In summary, Web APIs are useful, and... well... this one was actually a bitch to get working, but all in all, I'd say the code I generated in my project is more stable than scraping the data manually. Hopefully reading this guide encourages you to use this technology and build something that would have otherwise been 'not worth the time'. Good Luck.

0 Comments On This Entry


Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

April 2014

131415 16 171819


    Search My Blog

    0 user(s) viewing

    0 Guests
    0 member(s)
    0 anonymous member(s)