Menu Close

Server-Side Development with Hapi.js — Static File Directory and Input Validation

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.

Directory Handler Options

We can configure how static files are served with some options.

For instance, we can write:

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

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

  await server.register(require('@hapi/inert'));

  server.route({
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: Path.join(__dirname, 'public'),
        index: ['pic.png']
      }
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};

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

init();

We set the index option to set the file to serve if we don’t have any value set for the param URL parameter.

Static File Server

We can create a static file server with Hapi.

For example, we can write:

const Path = require('path');
const Hapi = require('@hapi/hapi');
const Inert = require('@hapi/inert');

const init = async () => {
  const server = new Hapi.Server({
    port: 3000,
    host: '0.0.0.0',
    routes: {
      files: {
        relativeTo: Path.join(__dirname, 'public')
      }
    }
  });

  await server.register(Inert);

  server.route({
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true
      }
    }
  });

  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 server with the routes.files.relativeTo option to specify the static files directory.

Then we call server.route to create a route to expose the static files.

The handler.directory.path property has the root path of the static files.

And redirectToSlash set to true means we treat the path with a trailing slash and no trailing slash to be the same.

Input Validation

We can add validation to our route to validate request data.

For example, we can write:

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

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

  server.route({
    method: 'GET',
    path: '/hello/{name}',
    handler (request, h) {
      return `Hello ${request.params.name}!`;
    },
    options: {
      validate: {
        params: Joi.object({
          name: Joi.string().min(3).max(10)
        })
      }
    }
  });

  await server.start();
  console.log('Server running at:', server.info.uri);
};

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

init();

to add validation.

We add the @hapi/joi module.

Then we add the options.validate.params property to add our validation for the URL request parameter.

We set the params property to the object returned by Joi.object call to validate the URL parameter.

Then inside it, we specify the parameters we want to validate.

The name property is set to Joi.string().min(3).max(10) so that we make sure it’s a string with a min length of 3 and max length of 10.

If the name parameter value doesn’t meet this requirement, then it’ll be rejected with a 400 response.

Conclusion

We can validate request URL parameters with @hapi/joi .

Also, we can serve static file directories with @hapi/inert .

Posted in Hapi