Menu Close

Server-Side Development with Hapi.js — Query Parameters and Request Payloads

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.

Query Parameters

We can get query parameters in our route handler with the request.query property.

For example, we can write:

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

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

  server.route({
    method: 'GET',
    path: '/',
    handler: function (request, h) {
      return `Hello ${request.query.name}!`;
    }
  });

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

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

init();

In the route handler, we use the request.query.name property to get the name property value.

Then when we make a GET request to /?name=foo , we see:

Hello foo!

returned as the response.

We can parse query strings with the query string parser of our choice.

For example, we can write:

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

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

  server.route({
    method: 'GET',
    path: '/',
    handler: function (request, h) {
      return request.query;
    }
  });

  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 query property to the object we passed into the Hapi.server function.

Then we set the parser method to return the object parsed by the Qs.parse method.

Request Payload

We can get the request body with the request.payload property.

For instance, we can write:

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

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

  server.route({
    method: 'POST',
    path: '/',
    handler: function (request, h) {
      return request.payload;
    }
  });

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

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

init();

We returned the request.payload property to return the request body as the response.

So when we make a POST request to the / route with the body:

{
    "foo": "bar"
}

Then we get the same thing back as the response.

Options

We can add some route options to configure our routes.

For example, we can write:

const Hapi = require('@hapi/hapi');
const Joi = require("@hapi/joi")

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

  server.route({
    method: 'POST',
    path: '/',
    options: {
      auth: false,
      validate: {
        payload: Joi.object({
          username: Joi.string().min(1).max(20),
          password: Joi.string().min(7)
        })
      }
    },
    handler: function (request, h) {
      return request.payload;
    }
  });

  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 @hapi/joi module with the validate.payload property.

We set that to the Joi.object property with an object that has the fields for the object.

username field is a string with a min length of 1 and a max length of 20 as specified by:

Joi.string().min(1).max(20)

And password is a string with a min length of 7 as specified by:

Joi.string().min(7)

auth is set to false to disable auth on the route.

Conclusion

Hapi routes can accept query parameters and request bodies.

Posted in Hapi