Serverless Hapi Services Using Stackery

Originally published at www.stackery.io.


Why?

Using serverless technologies for APIs provides multiple benefits:

  • Requests are handled in parallel with unbounded horizontal scalability.
  • Increased infrastructure efficiency because serverless functions run only when API requests are made. Infrequently accessed APIs no longer require base-line server instance costs.
  • Ops overhead is reduced as much of the engineering challenges around scalability are handled automatically by the infrastructure provider.

However, most serverless-based APIs are built by decomposing functionality into individual functions servicing only one endpoint. This can be challenging to maintain due to the complexities of managing helper functionality used across multiple endpoints.

Instead, we can build a single function servicing all requests using a mature, popular API framework like hapi. This way developers can use tools and techniques they are already familiar with to power their API services.

That’s Awesome! How?

You only need to make two small changes to your existing hapi app:

  1. Export your server object
  2. Start the server only when running the server directly

The second step is required to make it easy to continue running the server locally, while preventing the server’s network connection listening from keeping the serverless function from completing. Here’s how you can do this for an example app:

// Were we included from another file? const local = !module.parent; // Only start listening for requests if running server locally if (local) { server.start(function () { console.log('Server running at:', server.info.uri); }); }

Hook Me Up!

Now that your existing hapi app is ready for serverless, let’s integrate it into a Stackery Function! We simply need to translate the message emitted from the Rest Api node into an object understood by hapi, then translate the response from hapi back to the expected response for the Rest Api node. Here’s what that looks like:

const server = require('MyServer') module.exports = function handler(message) { /* Transform Stackery message to request message for hapi */ let request = { method: message.method, url: message.pathname, headers: message.headers, payload: message.body, remoteAddress: message.ip } return server.initialize() .then(() => server.inject(request)) .then((response) => { /* Transform hapi response to Stackery Rest Api response message */ return { statusCode: response.statusCode, headers: response.headers, body: response.rawPayload } }) }

Try It Out!

You can try this out by importing the hapi-serverless-example GitHub repo as a new stack in your Stackery account. Check out this guide for instructions. Give it a shot and let us know what you think!