49 Days of Ruby: Day 36 - APIs: Building HTTP Calls

Ben Greenberg - Apr 30 '21 - - Dev Community

Welcome to day 36 of the 49 Days of Ruby! 🎉

Web scraping, which we covered yesterday, is a great way to get information off of a website programmatically. However, there is an even better way, but only possible if a website builds it. We are talking about APIs.

Today we will build a sample call to a real-world API in Ruby.

First, what is an API?

An API, which stands for Application Programming Interface, is a programmed set of ways to interact with an application.

The APIs you will most often work with are interfaces to remote web servers, an alternative to fetching data from a website. They often provide you a lot more customizability in your request formation. APIs can allow you to create, read, update and delete (destroy) information depending on your access restrictions.

For example, you may have an account on DEV, and with the API you can create a new blog post, read (i.e. fetch) your blog posts, update your existing ones, or delete (i.e. destroy) ones you have already published. Those four actions are often referred to as CRUD actions.

Working with APIs in Ruby

Today, we are going to build a small request to read from the DEV API.

In this request, we are going to fetch all of Ben Halpern's articles by his username on DEV, which is ben.


require 'net/http'

url = URI("https://dev.to/api/articles?username=ben")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)

response = https.request(request)

response = JSON.parse(response.body) 
Enter fullscreen mode Exit fullscreen mode

The above request looks a lot like how we would start the process of web scraping data. With both web scraping and API calls, you still need to build an HTTP request. The difference is what you do after.

Web scraping gives you back the data as raw HTML. When you make a request to an API you get back the data typically in a more organized form, with keys and values that we can reference.

That's why in our last line in the code sample above, we parse the data into JSON. JSON is a way to store information. It stands for JavaScript Object Notation, although people will rarely call it that.

The result of that JSON.parse method call is something that will look like the following. It is sample data from the DEV API Reference Documentation:

{
  "type_of": "article",
  "id": 194541,
  "title": "There's a new DEV theme in town for all you 10x hackers out there (plus one actually useful new feature)",
  "description": "",
  "cover_image": 
  "https://res.cloudinary.com/practicaldev/image/fetch/s--74Bl23tz--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://res.cloudinary.com/practicaldev/image/fetch/s--xU8cbIK4--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_420%2Cq_auto%2Cw_1000/https://thepracticaldev.s3.amazonaws.com/i/8a39dzf3oovzc2snl7iv.png",
  "readable_publish_date": "Oct 24",
  "social_image": 
  "https://res.cloudinary.com/practicaldev/image/fetch/s--SeMxdKIa--/c_imagga_scale,f_auto,fl_progressive,h_500,q_auto,w_1000/https://res.cloudinary.com/practicaldev/image/fetch/s--xU8cbIK4--/c_imagga_scale%2Cf_auto%2Cfl_progressive%2Ch_420%2Cq_auto%2Cw_1000/https://thepracticaldev.s3.amazonaws.com/i/8a39dzf3oovzc2snl7iv.png",
  "tag_list": [
    "meta",
    "changelog",
    "css",
    "ux"
  ],
  "tags": "meta, changelog, css, ux",
  "slug": "there-s-a-new-dev-theme-in-town-for-all-you-10x-hackers-out-there-plus-one-actually-useful-new-feature-2kgk",
  "path": "/devteam/there-s-a-new-dev-theme-in-town-for-all-you-10x-hackers-out-there-plus-one-actually-useful-new-feature-2kgk",
  "url": "https://dev.to/devteam/there-s-a-new-dev-theme-in-town-for-all-you-10x-hackers-out-there-plus-one-actually-useful-new-feature-2kgk",
  "canonical_url": "https://dev.to/devteam/there-s-a-new-dev-theme-in-town-for-all-you-10x-hackers-out-there-plus-one-actually-useful-new-feature-2kgk",
  "comments_count": 37,
  "positive_reactions_count": 12,
  "public_reactions_count": 142,
  "collection_id": null,
  "created_at": "2019-10-24T13:41:29Z",
  "edited_at": "2019-10-24T13:56:35Z",
  "crossposted_at": null,
  "published_at": "2019-10-24T13:52:17Z",
  "last_comment_at": "2019-10-25T08:12:43Z",
  "published_timestamp": "2019-10-24T13:52:17Z",
  "reading_time_minutes": 15,
  "user": {
  "name": "Ben Halpern",
  "username": "ben",
  "twitter_username": "bendhalpern",
  "github_username": "benhalpern",
  "website_url": "http://benhalpern.com",
  "profile_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--Y1sq1tFG--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/1/f451a206-11c8-4e3d-8936-143d0a7e65bb.png",
  "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--DcW51A6v--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/1/f451a206-11c8-4e3d-8936-143d0a7e65bb.png"
},
  "organization": {
    "name": "The DEV Team",
    "username": "devteam",
    "slug": "devteam",
    "profile_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--0kDBq1Ne--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://thepracticaldev.s3.amazonaws.com/uploads/organization/profile_image/1/0213bbaa-d5a1-4d25-9e7a-10c30b455af0.png",
    "profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--8tTU-XkZ--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://thepracticaldev.s3.amazonaws.com/uploads/organization/profile_image/1/0213bbaa-d5a1-4d25-9e7a-10c30b455af0.png"
    }
  }
]
Enter fullscreen mode Exit fullscreen mode

That's a lot of data!

How would we interact with that! We can reference points in it like it was a hash:

> puts response["id"]

# => 194541
Enter fullscreen mode Exit fullscreen mode

If you try that at home in your own terminal you can experiment by accessing different parts of the data returned to you. Congrats, you've made your first API call in Ruby!

Come back tomorrow for the next installment of 49 Days of Ruby! You can join the conversation on Twitter with the hashtag #49daysofruby.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .