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.
Base64 Encoding
We can handle base64 encoding and decoding with the @hapi/b64
module.
For instance, we can write:
const Path = require('path');
const Hapi = require('@hapi/hapi');
const Fs = require('fs');
const B64 = require('@hapi/b64');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0',
debug: { request: ['error'] }
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
const stream = Fs.createReadStream(Path.join(__dirname, 'package.json'));
const encoder = new B64.Encoder();
stream.pipe(encoder).pipe(process.stdout);
return 'success'
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call Fs.createReadStream
to create the srean.
Then we create the encoder
object with the B64.Encoder
constructor.
And then we pass the encoder to the stream.pipe
method to encode the stream into a base64 string.
And then we pass that into stdout
with another pipe
call.
Base64 Decoding
We can decode base64 text into its original content with the @hapi/b64
module.
To do this, we write:
const Path = require('path');
const Hapi = require('@hapi/hapi');
const Fs = require('fs');
const B64 = require('@hapi/b64');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0',
debug: { request: ['error'] }
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
const stream = Fs.createReadStream(Path.join(__dirname, 'encodedfile.b64'));
const decoder = new B64.Decoder();
stream.pipe(decoder).pipe(process.stdout);
return 'success'
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call the Fs.createReadStream
to create the read stream and read the file with the given path.
Then we create the decoder
object with the B64.Decoder
constructor.
And then we call stream.pipe
with the decoder
to do the decoding.
Then we call pipe
again to pipe the decoded content to stdout
.
Error Response
We can add a login route easily with the @hapi/boom
module.
To use it, we write:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
throw Boom.badRequest('invalid query');
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call Boom.badRequest
to create an Error
object that we can throw.
It takes the error message as the argument.
Then we throw that and we should see:
{"statusCode":400,"error":"Bad Request","message":"invalid query"}
returned as the response.
We can check if an object is an instance of the Boom.Boom
constructor by writing:
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const init = async () => {
const server = new Hapi.Server({
port: 3000,
host: '0.0.0.0'
});
server.route({
method: 'GET',
path: '/',
handler(request, h) {
const err = Boom.badRequest('invalid query');
return Boom.isBoom(err);
}
});
await server.start();
console.log('Server running at:', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
We call Boom.isBoom
to do the check.
It should return true
since err
is an instance of Boom.Boom
.
Conclusion
We can return error responses easily with the @hapi/boom
module.
The @hapi/base64
module lets us encode and decode base64 content.