Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Accelerating Server-Side Development with Fastify

You're reading from  Accelerating Server-Side Development with Fastify

Product type Book
Published in Jun 2023
Publisher Packt
ISBN-13 9781800563582
Pages 406 pages
Edition 1st Edition
Languages
Authors (3):
Manuel Spigolon Manuel Spigolon
Profile icon Manuel Spigolon
Maksim Sinik Maksim Sinik
Profile icon Maksim Sinik
Matteo Collina Matteo Collina
Profile icon Matteo Collina
View More author details

Table of Contents (21) Chapters

Preface 1. Part 1:Fastify Basics
2. Chapter 1: What Is Fastify? 3. Chapter 2: The Plugin System and the Boot Process 4. Chapter 3: Working with Routes 5. Chapter 4: Exploring Hooks 6. Chapter 5: Exploring Validation and Serialization 7. Part 2:Build a Real-World Project
8. Chapter 6: Project Structure and Configuration Management 9. Chapter 7: Building a RESTful API 10. Chapter 8: Authentication, Authorization, and File Handling 11. Chapter 9: Application Testing 12. Chapter 10: Deployment and Process Monitoring for a Healthy Application 13. Chapter 11: Meaningful Application Logging 14. Part 3:Advanced Topics
15. Chapter 12: From a Monolith to Microservices 16. Chapter 13: Performance Assessment and Improvement 17. Chapter 14: Developing a GraphQL API 18. Chapter 15: Type-Safe Fastify 19. Index 20. Other Books You May Enjoy

From a Monolith to Microservices

Our little application has started gaining traction, and the business has asked us to redesign our API while keeping the previous version running to ease the transition. So far, we have implemented a “monolith” – all of our application is deployed as a single item. Our team is very busy with evolutive maintenance, which we cannot defer. Then, our management has a “Eureka!” moment: let’s add more staff.

Most engineering management books recommend that the team size should never increase beyond eight people – or if you’re Amazon, no larger than the amount that can share two large pizzas (that’s Jeff Bezos’s two-pizza rule). The reason is that with over eight people, the number of interconnections between team members grows exponentially, making collaboration impossible. An often overlooked solution is to not grow the team, but rather slow down delivery.

A solution to our growing...

Technical requirements

As mentioned in the previous chapters, you will need the following:

  • A working Node.js 18 installation
  • A text editor to try the example code
  • Docker
  • An HTTP client to test out code, such as CURL or Postman
  • A GitHub account

All the snippets in this chapter are on GitHub at https://github.com/PacktPublishing/Accelerating-Server-Side-Development-with-Fastify/tree/main/Chapter%2012.

Implementing API versioning

Fastify provides two mechanisms for supporting multiple versions of the same APIs:

In this section, we will cover how to apply both techniques, starting with the following base server:

// server.js
const fastify = require('fastify')()
fastify.get('/posts', async (request, reply) => {
  return [{ id: 1, title: 'Hello World' }]
})
fastify.listen({ port: 3000 })

Version constraints

The Fastify constraint system allows us to expose multiple routes on the same URL by discriminating by HTTP header. It’s an advanced methodology that changes how the user must call our API: we must specify an Accept-Version header containing a semantic versioning...

Splitting the monolith

In the previous section, we discovered how to structure our application using Fastify plugins, separating our code into services and routes. Now, we are moving our application to the next step: we are going to split it into multiple microservices.

Our sample application has three core files: our routes for v1 and v2, plus one external service to load our posts. Given the similarity between v1 and v2 and our service, we will merge the service with v2, building the “old” v1 on top of it.

We are going to split the monolith across the boundaries of these three components: we will create a “v2” microservice, a “v1” microservice, and a “gateway” to coordinate them.

Creating our v2 service

Usually, the simplest way to extract a microservice is to copy the code of the monolith and remove the parts that are not required. Therefore, we first structure our v2 service based on the monolith, reusing the routes...

Exposing our microservice via an API gateway

We have split our monolith into two microservices. However, we would still need to expose them under a single origin (in web terminology, the origin of a page is the combination of the hostname/IP and the port). How can we do that? We will cover an Nginx-based strategy as well as a Fastify-based one.

docker-compose to emulate a production environment

To demonstrate our deployment scenario, we will be using a docker-compose setup. Following the same setup as in Chapter 10, let’s create a Dockerfile for each service (v1 and v2). The only relevant change is replacing the CMD statement at the end of the file, like so:

CMD ["node", "server.js"]

We’ll also need to create the relevant package.json file for each microservice.

Once everything is set up, we should be able to build and run both v1 and v2 that we just created. To run them, we set up a docker-compose-two-services.yml file like the following...

Implementing distributed logging

Once we have created a distributed system, everything gets more complicated. One of the things that becomes more complicated is logging and tracing a request across multiple microservices. In Chapter 11, we covered distributed logging – this is a technique that allows us to trace all the log lines that are relevant to a specific request flow via the use of correlation IDs (reqId). In this section, we will put that into practice.

First, we modify our gateway’s server.js file to generate a new UUID for the request chain, like so:

const crypto = require('crypto')
const fastify = require('fastify')({
  logger: true,
  genReqId (req) {
    const uuid = crypto.randomUUID()
    req.headers['x-request-id'] = uuid
    return uuid
  }
})

Note that we generate a new UUID at every request and assign it back to the headers...

Summary

In this chapter, we discussed the problems with deploying a monolith and the different techniques to mitigate these issues: constraints and URL prefixing. The latter is the foundation for the ultimate solution: splitting the monolith into multiple microservices. Then, we showed how to apply distributed logging to a microservices world, ensuring that the requests are uniquely identifiable across different microservices.

You are ready to proceed to Chapter 13, in which you will learn how to optimize your Fastify application.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Accelerating Server-Side Development with Fastify
Published in: Jun 2023 Publisher: Packt ISBN-13: 9781800563582
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}