Reader small image

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

Product typeBook
Published inJun 2023
Reading LevelBeginner
PublisherPackt
ISBN-139781800563582
Edition1st Edition
Languages
Tools
Right arrow
Authors (3):
Manuel Spigolon
Manuel Spigolon
author image
Manuel Spigolon

Manuel Spigolon is a Senior Backend Developer at Near Form. He is one of core maintainers on the Fastiy team. Manuel has developed and maintained a complex API that serves more than 10 millions world wide.
Read more about Manuel Spigolon

Maksim Sinik
Maksim Sinik
author image
Maksim Sinik

Maksim Sinik is a senior engineering manager and a core maintainer of the Fastify framework. He has a decade of experience as a Node.js developer with a strong interest in backend scalability. He designed the architecture and led the development of several service-based Software-as-a-Service (SaaS) platforms across multiple industries that process hundreds of thousands of requests.
Read more about Maksim Sinik

Matteo Collina
Matteo Collina
author image
Matteo Collina

Matteo Collina is the co-founder and CTO of Platformatic who has the goal of removing all friction from backend development. He is also a prolific open source author in the JavaScript ecosystem, and the modules he maintains are downloaded more than 17 billion times a year. Previously, he was the chief software architect at NearForm, the best professional services company in the JavaScript ecosystem. In 2014, he defended his Ph.D. thesis titled Application Platforms for the Internet of Things. Matteo is a member of the Node.js Technical Steering Committee, focusing on streams, diagnostics, and HTTP. He is also the author of the fast logger, Pino, and the Fastify web framework. Matteo is a renowned international speaker after more than 60 conferences, including OpenJS World, Node.js Interactive, NodeConf.eu, NodeSummit, JSConf.Asia, WebRebels, and JsDay, to name just a few. Since August 2023, he also serves as a community director on the OpenJS Foundation. In the summer, he loves sailing the Sirocco.
Read more about Matteo Collina

View More author details
Right arrow

Building a RESTful API

In this chapter, we will build upon the scaffolding structure we created in the previous chapter and dive into writing the essential parts of our application.

We will start by defining the routes of our application and then move on to connecting to data sources. We will also implement the necessary business logic and learn how to solve complex everyday tasks that we may encounter while developing a real-world Fastify application.

The chapter will be divided into several main headings, starting with defining the routes, then connecting to data sources, implementing the routes, securing the endpoints, and applying the Don’t Repeat Yourself (DRY) principle to make our code more efficient.

By the end of this chapter, we will have learned the following:

  • How to declare and implement routes using Fastify plugins
  • How to add JSON schemas to secure the endpoints
  • How to load route schemas
  • How to use decorators to implement the DRY pattern...

Technical requirements

To follow along with this chapter, you will need these exact technical requirements, mentioned in the previous chapters:

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

So, let’s get started and build a robust and efficient application that we can use as a reference for future projects!

Application outline

In this section, we will start building a RESTful to-do application. The application will allow users to perform Create, Read, Update, and Delete (CRUD) operations on their to-do list, using HTTP methods such as GET, POST, PUT, and DELETE. Besides those operations, we will implement one custom action to mark tasks as “done.”

What is RESTful?

Representational State Transfer (RESTful) is an architectural style to build web services that follow well-defined constraints and principles. It is an approach for creating scalable and flexible web APIs that different clients can consume. In RESTful architecture, resources are identified by Uniform Resource Identifiers (URIs). The operations performed on those resources are based on predefined HTTP methods (GET, POST, PUT, DELETE, etc.). Every call to the API is stateless and contains all the information needed to perform the operation.

Fastify is an excellent choice to develop RESTful APIs, due to its...

Implementing the routes

Until now, we implemented our handlers as dummy functions that don’t do anything at all. This section will teach us how to save, retrieve, modify, and delete actual to-do tasks using MongoDB as the data source. For every subsection, we will examine only one handler, knowing that it will replace the same handler we already defined in ./routes/todos/routes.js.

Unique identifiers

This section contains several code snippets and commands to issue in the terminal. It is important to remember that the unique IDs we show here are different from the ones you will have when testing the routes. In fact, the IDs are generated when a task is created. Change the command snippets accordingly.

We will start with createTodo since having items saved on the database will help us implement and test the other handlers.

createTodo

As the name implies, this function allows users to create new tasks and save them to the database. The following code snippet defines...

Securing the endpoints

So far, every route we declared doesn’t perform any check on the input the user passes. This isn’t good, and we, as developers, should always validate and sanitize the input of the APIs we expose. In our case, all the createTodo and updateTodo handlers are affected by this security issue. In fact, we take the request.body and pass it straight to the database.

First, to better understand the underlying issue, let’s give an example of how a user can inject undesired information into our database with our current implementation:

$ curl -X POST http://localhost:3000/todos -H "Content-Type: application/json" -d '{"title": "awesome task", "foo": "bar"}'
{"id": "6418214ad5e0cccc313cda85"}%
$ curl http://127.0.0.1:3000/todos/6418214ad5e0cccc313cda85
{"id": "6418214ad5e0cccc313cda85", "title": "awesome task", "foo"...

Loading route schemas

Before implementing the schemas, let’s add a dedicated folder to organize our code base better. We can do it inside the ./routes/todos/ path. Moreover, we want to load them automatically from the schemas folder. To be able to do that, we need the following:

  • A dedicated plugin inside the schemas folder
  • A definition of the schemas we wish to use
  • An autohooks plugin that will load everything automatically when the todos module is registered on the Fastify instance

We will discuss these in detail in the following subsections.

Schemas loader

Starting with the first item of the list we just discussed, we want to create a ./routes/todos/schemas/loader.js file. We can check the content of the file in the following code snippet:

'use strict'
const fp = require('fastify-plugin')
module.exports = fp(async function schemaLoaderPlugin (fastify, opts) { // [1]
  fastify.addSchema(require('./list-query...

Don’t repeat yourself

Defining the application logic inside routes is fine for simple applications such as the one in our example. In a real-world scenario, though, when we need to use our logic across an application in multiple routes, it would be nice to define that logic only once and reuse it in different places. So, once more, Fastify has us covered.

We can expand our autohooks.cjs plugin by adding what is commonly known as a data source. In the following snippet, we expand the previous plugin, adding the needed code, although, for the brevity of the exposition, we are showing only the function for the createTodo handler; you can find the whole implementation inside the book’s code repository:

'use strict'
const fp = require('fastify-plugin')
const schemas = require('./schemas/loader')
module.exports = fp(async function todoAutoHooks (fastify, opts) { // [1]
  const todos = fastify.mongo.db.collection('todos&apos...

Summary

This chapter taught us step by step how to implement a RESTful API in Fastify. First, we used the powerful plugin system to encapsulate our route definitions. Then, we secured our routes and database accesses using schema definitions. Finally, we moved the application logic inside a dedicated plugin using decorators. This allowed us to follow the DRY pattern and make our application more maintainable.

The following chapter will look at user management, sessions, and file uploads to extend the application’s capabilities even more.

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 2023Publisher: PacktISBN-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.
undefined
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

Authors (3)

author image
Manuel Spigolon

Manuel Spigolon is a Senior Backend Developer at Near Form. He is one of core maintainers on the Fastiy team. Manuel has developed and maintained a complex API that serves more than 10 millions world wide.
Read more about Manuel Spigolon

author image
Maksim Sinik

Maksim Sinik is a senior engineering manager and a core maintainer of the Fastify framework. He has a decade of experience as a Node.js developer with a strong interest in backend scalability. He designed the architecture and led the development of several service-based Software-as-a-Service (SaaS) platforms across multiple industries that process hundreds of thousands of requests.
Read more about Maksim Sinik

author image
Matteo Collina

Matteo Collina is the co-founder and CTO of Platformatic who has the goal of removing all friction from backend development. He is also a prolific open source author in the JavaScript ecosystem, and the modules he maintains are downloaded more than 17 billion times a year. Previously, he was the chief software architect at NearForm, the best professional services company in the JavaScript ecosystem. In 2014, he defended his Ph.D. thesis titled Application Platforms for the Internet of Things. Matteo is a member of the Node.js Technical Steering Committee, focusing on streams, diagnostics, and HTTP. He is also the author of the fast logger, Pino, and the Fastify web framework. Matteo is a renowned international speaker after more than 60 conferences, including OpenJS World, Node.js Interactive, NodeConf.eu, NodeSummit, JSConf.Asia, WebRebels, and JsDay, to name just a few. Since August 2023, he also serves as a community director on the OpenJS Foundation. In the summer, he loves sailing the Sirocco.
Read more about Matteo Collina