Shares

Hacker News released its API to the world a few days ago. Data geeks previously had to rely on web scraping and paginated results to obtain data from the Hacker News site, but things have changed now. With Hacker News’ official API, we have a structured way to tap into the data. 

I’ve dabbled around the API a little bit and created a redesigned Hacker News front page using Vanilla PHP and Guzzle. Guzzle is a HTTP client for consuming APIs. The current live demo and code repo are given below.

Demo | Code

Composer.json

At first, we require the necessary libraries for our demo to function. This is the composer.json. Guzzle is an awesome PHP library for consuming APIs using PHP. Carbon is a gorgeous date time library for turning timestamps into human readable dates.

 {
"require": {
    "guzzlehttp/guzzle": "~4.0",
    "nesbot/Carbon": "*"
 }
} 

Once you have created the composer.json file in your app directory, simply do composer install, or composer update. This will generate optimized autoloader files which you can use in your application.

HackerNewsInterface.php

I usually start off by writing an Interface. This allows me to follow a specific contract of what my Class is trying to achieve. Here is the HackerNewsInterface.php which clearly specifies what resources of the Hacker News API are being consumed.


<?php

//interface to ensure a contract is followed
interface HackerNewsInterface {

public function get_top_stories_ids();
public function get_item_data_by_id($item_id);
public function get_user_data_by_id($user_id);

}

What are we trying to do here? Well, we are trying to redesign the Hacker News front page showing some top entries. By reading the Interface, you get the idea: we get the top stories IDs, use those to get their specific information, and further, use that to pull up user data. It’s like a chain and each component utilizes the core functionality offered by the Hacker News API.

HackerNews.php

HackerNews.php is the magician. It does the work. Here’s how it looks like. I am sure it’s fairly straight forward from here on. The documentation is provided on top of each function, here in this code snippet, and on the code repository on Github, for your perusal.


<?php

require 'vendor/autoload.php';

require_once('HackerNewsInterface.php');

class HackerNews implements HackerNewsInterface {

/*
 * Get Top 100 Hacker News Stories
 * @return Array of IDs
 */

public function get_top_stories_ids() {

$client = new GuzzleHttp\Client();

$res = $client->get('https://hacker-news.firebaseio.com/v0/topstories.json');

$data = $res->json();

return $data;
 }
 /*
 * Get Item Data for a Story using ID
 * @return Array of Item Data
 */

public function get_item_data_by_id($item_id) {

$client = new GuzzleHttp\Client();

$item_resource = "https://hacker-news.firebaseio.com/v0/item/" . $item_id . ".json";

$res = $client->get($item_resource);

$data = $res->json();

return $data;

}

/*
 * Get User data for a User using ID
 * @return Array of User Data
 */
 public function get_user_data_by_id($user_id) {

$client = new GuzzleHttp\Client();

$user_resource = "https://hacker-news.firebaseio.com/v0/user/" . $user_id . ".json";

$res = $client->get($user_resource);

$data = $res->json();

return $data;

}

}

Sweet, now let’s get to some design work with index.php.

Index.php

At top of index.php, we have this snippet, which boots up the class. The rest of the file is a mixture of HTML and PHP.


<?php

require_once('HackerNews.php');

//carbon library
use Carbon\Carbon;

//initialize our class
$api = new HackerNews();

//get the list of top 100 stories
$top_items_full= $api->get_top_stories_ids();

//slice that down to 10
$top_items = array_slice($top_items_full, 0, 10);
?>

Once we have the HackerNews class initialized, we pull in the stories array and loop over it. At the same time, we style it with PureCSS.io’s slick design. The code below is essentially what loops over each story on Hacker News in real-time and displays the top 10.


<div class="posts">
 <h1 class="content-subhead">Top Stories</h1>
 <?php foreach ($top_items as $item_id) {
 $item = $api->get_item_data_by_id($item_id);
 $user = $api->get_user_data_by_id($item['by']);
 ?>

<section class="post">
 <header class="post-header">

<h2 class="post-title"><a target="_blank" href="<?php echo $item['url']; ?>"><?php echo $item['title']; ?> </a></h2>

<p class="post-meta">
 By <a title="<?php echo $user['karma']; ?>" href="#" class="post-author"><?php echo $item['by']; ?></a> with score of <a class="post-category post-category-design" href="#"> <?php echo $item['score']; ?></a> <a class="post-category post-category-pure" href="#"> <?php echo Carbon::createFromTimeStamp($item['time'])->diffInHours();?> hours ago </a>
 </p>
 </header>
 </section>

 <?php } ?>
 </div>

Final Result

You can see it live here or below.

About Ali Gajani

Hi. I am Ali Gajani. I started Mr. Geek in early 2012 as a result of my growing enthusiasm and passion for technology. I love sharing my knowledge and helping out the community by creating useful, engaging and compelling content. If you want to write for Mr. Geek, just PM me on my Facebook profile.