Build

Building a Serverless Hacker News Clone App

5 min read Adam Bavosa on Apr 3, 2019

PubNub provides a serverless environment for building real-time apps that scale instantly. With a single button click (or CLI command) you can deploy a serverless microservice to data centers around the world. As a developer, you don’t have to worry about infrastructure. PubNub automatically configures load balancing and autoscaling out of the box.

Features like Functions turns developers into superheroes. You can create a microservice in hours instead of weeks. Deploying is a breeze. Security is built in. Infrastructure development is no longer part of the equation. In this post, we will walk through the software development process for creating apps using the Functions On Request event handler.

In case you haven’t heard of that before, think of it as your app’s own REST API. PubNub provides you with a unique URL, which is the public, HTTPS access point to your back-end code. For this example, I have created a Hacker News clone that allows any user to post links, updated in real time. The app and API are hosted entirely in Functions.

Functions Serverless Hacker News Clone

Serverless Application

The conventional approach to web app development is to first rent a server, or part of a server, on a web hosting platform. This machine will host your app’s code and assets, so public facing users can interact with it freely. The developer or team of developers will need to deploy their code to this server whenever they make updates to the application.

In a serverless app, there are a lot of similarities. However, serverless shines when it comes to complications of server management, flexible scaling, high availability, and paying for idle capacity. Functions event handlers scale automatically based on your usage load, so customers do not witness slow-down or outages.

Your Functions code is deployed in a distributed fashion to data centers around the world. This means extremely low latency for all customers, regardless of their location. The PubNub Network keeps all of the instances state synchronized with real-time messaging under the hood. And Functions event handlers are always on. But PubNub customers pay by the number of executions of event handlers. All idle app instance time is free for PubNub customers.

Serverless Database

Functions can maintain application state using the KV Store. Your app can write data to any “key” and retrieve it later from the KV Store, with extremely low latency. This means your real-time app can store the state of users and resources. This No-SQL database solution enables Functions to offer the same abilities as conventional web apps.

API Routes

Using the same design pattern outlined in the Functions Crash Course post, we can create separate routes and controllers for a single endpoint URL. Here are the three routes that our app serves:

  • GET to getPage at “/”
  • GET to getSubmissions at “/?route=getSubmissions”
  • POST to postLink at “/?route=postLink”

Get the HTML, CSS, and JS for the web browser

The getPage method returns all of the front-end code. Functions allows the developer to set response headers. In this case, we set the return ‘Content-Type’ header to HTML. This way, web browsers accept the response payload as a web page.

const getPage = () => {
    const page = '<html>.....</html>';
    response.headers['Content-Type'] = 'text/html; charset=utf-8';
    return response.send(page);
};

Get an array of all link submissions

When the web page loads, all of the dynamic data on the page needs to be retrieved with a subsequent request. Our serverless API has an endpoint that interacts with the KV Store. Think of this as our protected database call. It retrieves all of the latest links that users submitted in the web app.

const getSubmissions = () => {
    return kvstore.get(SUBMISSION_OBJECT_KEY).then((submissionObject) => {
        submissionObject = submissionObject || defaultSubmissionsObject;
        return response.send(submissionObject.submissions);
    });
};

Post a new link

Users can submit new links to our public web application. They can do so using the UI on the web page. Hitting the Enter Key or the button in the submission area initiates a POST request to our back-end API.

There is a purposefully implemented rate-limit of 1 second per link submission. This is put in place to prevent spammers from posting links too rapidly. The method writes links to the KV Store, but we implemented a limit of 10 links. The true limit of KV Store entries is 32KB per value, and you can set as many keys and values as you wish.

const postLink = () => {
    if (!ValidURL(urlSubmission)) return response.send(400);
    if (urlSubmission.indexOf('http://') !== 0 && urlSubmission.indexOf('https://') !== 0) {
        urlSubmission = 'https://' + urlSubmission;
    }
    return kvstore.get(SUBMISSION_OBJECT_KEY).then((submissionObject) => {
        submissionObject = submissionObject || defaultSubmissionsObject;
        const lastSubmission = submissionObject.lastSubmission;
        if (lastSubmission && lastSubmission > requestTime - 1000)
            return response.send(400); // Maximum 1 submission per second
        submissionObject.lastSubmission = requestTime;
        if (submissionObject.submissions.length >= 10)
            submissionObject.submissions.shift();
        submissionObject.submissions.push(urlSubmission);
        kvstore.set(SUBMISSION_OBJECT_KEY, submissionObject);
        return response.send(200);
    });
};

Deploying your serverless microservice

Functions can be deployed using the web editor or the command line. To create your own Function, sign up for PubNub and log in.

Now that you have a PubNub account and you have created Pub/Sub keys, you can make a Function in the PubNub Admin Dashboard.

Click the FUNCTIONS button on the left and follow the instructions for creation (here is the quickstart if you get lost).

Create a Function in the admin dashboard

Once you have created an On Request event handler with a simple path (like “hn”), you can go grab the code from the Serverless Hacker News GitHub repo. Copy the code from on-request-handler.js and paste it into the code editor (Functions deploy CLI tool is here).

Functions Serverless Code Editor

Click the start button on the top right to globally deploy your function. Click the “Copy URL” button on the left to get your unique URL. Paste this link into your web browser address bar to visit your own instance of the Hacker News clone app!

If you want to edit the front-end web code, see the index.html file in the repository. When you make edits, minify the code, and paste it as the string value in the API event handler code (on-request-handler.js).

If you have questions about architecture and implementation of your microservices with Functions, please reach out to devrel@pubnub.com!

0