Menu Close

Server-Side Development with Hapi.js — User-Agent, Payload, Semantic Version, and Sorting

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.

Get User Agent Info

We can get user agent info from the request with the @hapi/scooter module.

To use it, we write:

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

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

  server.route({
    method: 'GET',
    path: '/',
    config: {
      handler(request, h) {
        return request.plugins.scooter;
      },
    }
  });
  await server.register(Scooter);
  await server.start();
  console.log('Server running at:', server.info.uri);
};

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

init();

We have await server.register(Scooter); to register the Scooter plugin.

And we use request.plugins.scooter to return the user agent object.

Semantic Versioning

We can use the @hapi/somever module to work with semantic version numbers.

For example, we can write:

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

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

  server.route({
    method: 'GET',
    path: '/',
    config: {
      handler(request, h) {
        return somever.compare('1.2.3', '1.2.5');
      },
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

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

init();

to compare 2 version numbers with the somever.compare method.

Then we get -1 returned since the first version number is earlier than the 2nd one.

Also, we can compare versions with the match method:

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

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

  server.route({
    method: 'GET',
    path: '/',
    config: {
      handler(request, h) {
        return somever.match('1.2.x', '1.2.5');
      },
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};

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

init();

And we get true since '1.2.x' includes '1.2.5' .

Parsing HTTP Payloads

We can parse HTTP payload with the @hapi/subtext module.

For example, we can write:

const Http = require('http');
const Subtext = require('@hapi/subtext');

Http.createServer(async (request, response) => {
  const { payload, mime } = await Subtext.parse(request, null, { parse: true, output: 'data' });
  response.writeHead(200, { 'Content-Type': 'text/plain' });
  response.end(`Payload contains: ${JSON.stringify(payload)}`);

}).listen(1337, '0.0.0.0');

console.log('Server running/');

We call Subtext.parse with the request object to parse it.

It returns a promise with an object with the payload and mime properties.

payload has the payload sent.

mime has the MIME type.

Sorting Text

We can sort text with the @hapi/topo module.

To use it, we write:

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

const morning = new Topo.Sorter();

morning.add('Nap', { after: ['breakfast', 'prep'] });
morning.add([
  'Make toast',
  'Pour juice'
], { before: 'breakfast', group: 'prep' });
morning.add('Eat breakfast', { group: 'breakfast' });

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0'
  });
  server.route({
    method: 'GET',
    path: '/',
    config: {
      handler(request, h) {
        return morning.nodes;
      },
    }
  });
  await server.start();
  console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});
init();

We create the morning object with the Topo.Sorter constructor.

Then we call morning.add to add the items we want to sort.

The after property specifies the items that come after the item in the first argument.

group lets us add items into groups.

Then we can get the sorted items with the morning.nodes property.

Conclusion

We can sort items with the @hapi/topo module.

The @hapi/subtext module lets us parse request payloads.

And @hapi/scooter returns user agent info.

@hapi/somever lets us compare semantic version strings.

Posted in Hapi