Mastering Fastify: Building Backend Apps with Async/Await
Written on
Introduction to Fastify
Fastify is a lightweight framework for Node.js, designed specifically for creating backend web applications.
In this guide, we will explore the creation of backend applications using Fastify and the powerful async/await syntax.
Using Async/Await in Fastify
We can implement async/await within our route handlers. Here's an example:
const fastify = require('fastify')();
const getData = () => Promise.resolve('foo');
const processData = (data) => Promise.resolve(data);
const opts = {
schema: {
response: {
200: {
type: 'string'}
}
}
};
fastify.get('/', opts, async function (request, reply) {
const data = await getData();
const processed = await processData(data);
return processed;
});
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0');} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
In this code, we define an async function as our route handler, allowing us to utilize await for promise execution. The reply.send method is also available to return data.
For instance, we can modify our code as follows:
fastify.get('/', opts, async function (request, reply) {
const data = await getData();
const processed = await processData(data);
reply.send(processed);
});
This example demonstrates how to send back responses using reply.send.
Handling Responses with Await
We can also use await with the reply.send method in an async callback:
fastify.get('/', opts, async function (request, reply) {
setImmediate(() => {
reply.send({ hello: 'world' });});
await reply;
});
In this case, we await the reply since we invoked reply.send in a setImmediate callback. When both a return value and reply.send(value) are used simultaneously, the first executed one takes priority.
Note that if you are using async/await with reply.send, you should not return a value. Conversely, if you're using async/await with promises, ensure you return the value and do not use reply.send or return undefined.
Implementing Route Prefixing
Fastify allows for route prefixing, which can be implemented as shown:
const fastify = require('fastify')();
fastify.register(require('./routes/v1/users'), { prefix: '/v1' });
fastify.register(require('./routes/v2/users'), { prefix: '/v2' });
const start = async () => {
try {
await fastify.listen(3000, '0.0.0.0');} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
For the route files, you can structure them like this:
routes/v1/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', async () => 'v1');
done();
};
routes/v2/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', async () => 'v2');
done();
};
Consequently, when accessing /v1/user, the response will be 'v1', and similarly, /v2/user will return 'v2'.
Conclusion
In summary, Fastify enables the use of async functions as route handlers and supports the implementation of route prefixes, enhancing the development of backend applications.
The video titled "Fastify - Build your first route" provides a visual guide to creating routes in Fastify, complementing the concepts discussed in this article.