Menu Close

Server-Side Development with Hapi.js — Server Method Cache

Hapi.js is a small Node framework for developing back end web apps.

In this article, we’ll look at how to create back end apps with Hapi.js.

Cache

We can cache method results with Hapi.

This is a great benefit that doesn’t come with regular functions.

For example, we can write:

const Hapi = require('@hapi/hapi');

const add = (x, y) => {
  return x + y;
};

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.method('add', add, {
    cache: {
      expiresIn: 60000,
      staleIn: 30000,
      staleTimeout: 10000,
      generateTimeout: 100
    }
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return server.methods.add(1, 2);
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

We add the cache property with the expiresIn property to set the expiry time. The time is in milliseconds.

staleIn sets when the data is invalidated. The time is in milliseconds.

stateTimeout sets the number of milliseconds before returning a stale value while a fresh value is generated.

generateTimeout is the number of milliseconds to wait before returning a timeout error.

We can replace expiresIn with expiresAt :

const Hapi = require('@hapi/hapi');

const add = (x, y) => {
  return x + y;
};

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.method('add', add, {
    cache: {
      expiresAt: '20:30',
      staleIn: 30000,
      staleTimeout: 10000,
      generateTimeout: 100
    }
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return server.methods.add(1, 2);
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

expiresAt is the time of day expressed in 24h notation in HH:MM format.

It’s time art which the cache records for the route expires.

It can’t be used together with expiresIn .

We can override the ttl of as a server per-invocation by setting the flags.ttl property.

For example, we can write:

const Hapi = require('@hapi/hapi');

const add = (x, y, flags) => {
  flags.ttl = 5 * 60 * 1000;
  return x + y;
};

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.method('add', add, {
    cache: {
      expiresAt: '20:30',
      staleIn: 30000,
      staleTimeout: 10000,
      generateTimeout: 100
    }
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return server.methods.add(1, 2);
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

to set the flags.ttl property to the timeout we want.

Generate a Custom Key

We can create a custom cache key for the cached results.

To do this, we write:

const Hapi = require('@hapi/hapi');

const add = (arr) => {
  return arr.reduce((a, b) => a + b);
};

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: '0.0.0.0'
  });

  server.method('add', add, {
    generateKey: (array) => array.join(',')
  });

  server.route({
    method: 'GET',
    path: '/',
    handler(request, h) {
      return server.methods.add([1, 2, 3]);
    }
  });

  await server.start();
  console.log('Server running on %s', server.info.uri);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

to add the generateKey method to generate a unique cache key with our own function.

Conclusion

We can change various cache options with Hapi server methods.

Posted in Hapi