In this article, we would see how Fastify handles file upload as we build an image gallery using Fastify and React. We would work with Cloudinary and Fastify-multer a Fastify alternative to the express middleware multer.
Introduction
Fastify is a web development framework inspired by Hapi and Express but it promises faster performance with low overhead.
Fastify excels when it comes to building a fast HTTP server; performing nearly twice as fast as Express. It claims to be the fastest Nodejs frameworks and benchmark back up their claim.
Fastify is built to be a very modular system and it is fully extensible with hooks, plugins and, decorators.
Fastify uses a plugin-based architecture similar to that of Hapi and provides the register API for working with them.
Also, the Fastify plugin model is based on the reentrant lock and graph-based. And plugins in Fastify could be a set of routes, server decorators, etc.
In addition, Fastify supports middleware but starting from v3.0.0, middleware is not supported out of the box. So external plugins such as fastify-express or middie are used to add middleware support.
Fastify provided alternatives to some express middlewares and uses Reusify to squeeze a 10% increase in performance when handling middleware.
In this article, we would see how Fastify handles file upload as we build an image gallery using Fastify and React. We would work with cloudinary and Fastify-multer a Fastify alternative to the express middleware multer.
Let’s get started with the prerequisite in the next section.
Prerequisite
To follow along in this article, here are a few prerequisites to note:
- Node.js and MongoDB installed
- Basic knowledge of MongoDB and Mongoose
- Basic knowledge of React
Getting started
To get started, we will first set up our server.
Follow the steps below to create the server:
- Create an npm project and install all the needed dependencies:
- Add start scripts:
Open the package.json file and edit the scripts section as follows:
- Set environment variables:
Since we want to set up cloudinary as we build our server it is important we set its environment variables now. Create a .env file in the root directory and add the following codes:
I have specified some values you need to change to the values of your Cloudinary account. The values given here would not work if used. You can get these values from your Cloudinary dashboard.
- In the root directory, create a src directory with an index.js file containing the following code:
In the code above we have configured Cloudinary and created a Cloudinary image storage for multer.
Multer is an express middleware for handling multipart/form-data; it would not process any form which is not multipart and it is primarily used for uploading files.
Also, by default, Fastify does not parse multipart form data; it requires an external plugin like fasitfy-multipart or multer to add multipart support.
In this article, we are using fastify-multer which is a port of express multer and multer storage cloudinary — used to configure our Multer storage to Cloudinary.
Finally, we decorate Fastify with our image parser; this exposes the parser across our application. We will talk more about using the parser when we build our routes.
- Create the status route and test the server:
In the src directory, create a routes directory and a status.js file inside.
Add the following code to the status.js:
Our route above uses a custom log level warn. And the handler method in our route options object above specifies the function to handle this request.
Next, register out status route by adding the following codes below the // // Register plugins below in the index.js file:
Now we can test the server by running the codes below:
Our server is working so we will proceed to building our APIs in the next section.
Building our image gallery APIs
Create Models
In the src directory create a config directory with an index.js file and a models, directory. Inside the models directory, create a gallery.js file with the following codes:
Connecting to MongoDB using Mongoose
In the index.js file in the config directory add the following code:
The code above connects our app to MongodDB using mongoose and logs the connection status to the console and decorates Fastify with our model.
Create Upload Route Using Multer and Cloudinary
To create our endpoints, create a gallery.js file in the routes directory with the following codes:
Our routes above are built using full declaration, and in the route option object, the handler function handles the request. In the post endpoint, we use the prehandler hook to handle the file upload using multer.
Register plugins and test server
To register our plugins add the following code below the // Register plugins below: in the index.js file as seen below:
Note we need to import our mongoose configuration. Add the following codes to the list of imported modules in the index.js file:
Not we can test the sever by running:
We get:
Test Routes
- POST /gallery:
Note you should add more images for the React gallery.
- GET /gallery:
Consume API with React
App setup
To setup our React application follow the steps below:
Install dependencies
To install our app dependencies run the following code:
Add the Gallery and Error components
In the src directory, create a Gallery.js with the code below:
The Gallery.js component above fetches data from our backend — http://127.0.0.1:5000/gallery once our component mounts. Then it modifies this data to an array of objects containing two keys namely: original and thumbnail. This data structure is required by the react-image-gallery library we are using in this project.
Lastly, it displays the image gallery if there are images and an error message — using the ErrorMessage component if there are no images.
Next, create the ErrorMessage component by creating an Error.js file with the code below:
This component simply takes a message prop and displays it
Finally update our App.js with the codes below:
Start app and enable cors
To start our app we run:
Before we can successfully query our server we need to enable cors. To do this we will use fastify-cors. Register the fastify-cors package as a plugin in our server — index.js:
also import the fastify-cors module:
This configures the Access-Control-Allow-Origin CORS header to allow requests from localhost:3000.
We can start our React server now and our final app looks like this — note your uploaded images would be displayed instead:
Conclusion
It is a real joy to work with Fastify. The developer experience is great and the plugin model is really cool. One great thing about Fastify is that it allows us to use express middlewares modules — which is a huge collection of matured modules.
In this article, we handled our image upload with fastify-multer which is a port of express multer middleware. Another alternative to multer is fastify multipart; a plugin to parse the multipart content-type.
Also, Fastify provides alternatives to the most commonly used middleware, such as fastify-helmet in case of helmet, fastify-cors for cors and fastify-static for serve-static.
Finally, I do hope that after this article, you are willing and ready to give Fastify a try in your next project.