Introducción a fastify
6 minutos de lectura

Índice
Fastify es un framework para NodeJS donde su mayor característica es su rapidez, también es de poca carga, tiene más de 20 mil estrellas en github y es casi 4 veces más rápido que express.
Explicaremos como hacer un crud de tareas y conectarlo a mongodb usando esta tecnología.
Instalación
Para instalarlo debemos ejecutar el siguiente comando en la terminal de nuestro proyecto.
Con npm:
$ npm install fastify
Con yarn:
$ yarn add fastify
Luego crearemos una carpeta src y dentro un archivo index.js, aquí es donde estará el código de nuestro backend.
Crear un servidor
Luego de instalarlo debemos importarlo y ejecutarlo, luego lo ponemos en escucha y lo probamos con una ruta.
1// Importamos fastify2const app = require('fastify')({ logger: true });34// Colocamos una ruta5app.get('/', (req, res) => {6 res.send("Hello World")7})89// Colocamos el puerto para el servidor10const port = process.env.PORT || 30001112// Ponemos en escucha el servidor13app14 .listen(port)15 // Nos mostrara en consola la dirección en la cual está escuchando nuestro servidor16 .then((adress) => console.log(`Server listening at ${adress}`))17 .catch((error) => {18 app.log.error(error);19 process.exit(1);20 });
Luego podemos iniciar el servidor con el siguiente comando en la terminal
$ node src/index
Y podremos ver que el servidor se ha iniciado en la dirección http://127.0.0.1:3000, si realizamos una petición GET a esa dirección tendremos como resultado el string de "Hello world".
Instalar Nodemon
En caso que hagamos un cambio en el código tendremos que volver a ejecutar el comando para iniciar el servidor, pero existe nodemon que nos soluciona este problema.
Para instalarlo debemos ejecutar el siguiente comando en nuestro proyecto.
Con npm:
$ npm install nodemon --save-dev
Con yarn:
$ yarn add --dev nodemon
Y añadimos los siguientes scripts en nuestro archivo package.json
1"scripts": {2 "start": "node src/index",3 "dev": "nodemon src/index"4}
De esta manera usamos el comando npm run dev y cada cambio que se realice en el código se actualizara sin necesidad de volver a ejecutarlo.
Conectarlo a mongodb con mongoose
En nuestro caso para hacer una conexión con mongodb usaremos mongoose que nos facilita gran parte del trabajo y dotenv para proteger nuestras claves con variables de entorno.
Para instalarlos debemos ejecutar el siguiente comando en nuestro proyecto.
Con npm:
$ npm install mongoose dotenv
Con yarn:
$ yarn add fastify dotenv
Crearemos un archivo .env en la raíz de nuestro proyecto y allí colocaremos nuestra uri de mongodb.
1MONGODB_URI={Nuestra uri de mongodb}
También creamos un archivo .gitignore para que node_modules y nuestro archivo con las variables de entorno no se guarden en git.
1node_modules2.env
Crearemos otro archivo llamado mongo.js para conectar la base de datos y haremos lo siguiente
1// Importamos connect de mongoose2const { connect } = require('mongoose');34// Importamos dotenv para habilitar las variables de entorno5require('dotenv').config();67// Colocaremos esta configuración8const options = {9 useNewUrlParser: true,10 useUnifiedTopology: true,11 useFindAndModify: false,12 useCreateIndex: true,13};1415// Y realizamos la conexión16connect(process.env.MONGODB_URI, options)17 // Si la conexión es exitosa se nos mostrará en18 // consola el mensaje de 'Database connected'19 .then(() => console.log('Database connected'))20 // En caso contrario nos mostrara en consola un error21 .catch((error) => console.error(error));
Luego este archivo podemos importarlo colocando require('./mongo') en nuestro archivo de index.js.
Rutas
Podemos modularizar nuestras rutas y tener mucho más ordenado el código haciéndolo de esta manera.
1// Nos da los parámetros de app, options y el done.2const tasks = (app, options, done) => {34 // Y podremos añadir las rutas que queramos5 app.get('/tasks', (req, res) => {6 res.send('Hello World')7 })89 // Debemos ponerlo para declarar el fin de las diferentes rutas10 done()11}1213module.exports = tasks
Este código lo dejaremos en un archivo para luego registrarlo, en este caso en una nueva carpeta routes y un archivo llamado tasks.js.
Para importar y registrar las rutas lo haremos de la siguiente manera en nuestro archivo index.js.
1app.register(require('./routes/tasks'))
Añadir esquemas con mongoose
Para definir la estructura de los documentos podemos usar los esquemas de mongoose, estos los tendremos en una carpeta models y cada uno tendrá su archivo propio.
1// Importamos Schema y model de mongoose2const { Schema, model } = require('mongoose')34// Creamos el esquema que definirá la estructura de cada tarea5const taskSchema = new Schema({6 // Este será el contenido de cada tarea, el cual debe ser tipo string7 // y ser necesario para la creación de una tarea8 content: {9 type: 'string',10 required: true,11 },12 // Boleano que indicará si la tarea en cuestión se ha completado o no13 done: Boolean,14})1516// Creamos el modelo y lo exportamos17const Task = model('task', taskSchema)1819module.exports = Task
Controladores y crear el crud
Los controladores que pasaremos a cada ruta los añadiremos en una carpeta controllers y en un archivo llamado tasks.js. También importaremos el esquema que usaremos repetidas veces.
1const Task = require('../models/task');23const getTasks = (req, res) => {4 res.send('Hello World')5}67module.exports = { getTasks }
Y los importamos en nuestro archivo de rutas.
1const { getTasks } = require('../controllers/tasks')23const tasks = (app, options, done) => {4 app.get('/tasks', getTasks)56 done()7}89module.exports = tasks
Luego de hacer todo esto ya tenemos todo listo para crear el crud.
Obtener todas las tareas
Usaremos el método find para obtener todos los documentos que tengan el esquema que definimos.
1const getTasks = (req, res) => {2 Task.find()3 // Si la operación fue exitosa, nos manda4 // como respuesta todas las tareas5 .then((results) => res.send(results))6 // En su defecto nos muestra por consola el error7 .catch((error) => console.error(error))8}
Obtener una tarea por su identificador
Para esta ruta debemos usar el id que nos llega de los parámetros de la solicitud.
1// Colocamos el parámetro de id en la ruta2app.get('/tasks/:id', getTask);
1const getTask = (req, res) => {2 // Obtenemos el id de los parámetros de la solicitud3 const { id } = req.params;45 // Aplicaremos el método findById, a este debemos pasarle el id6 Task.findById(id)7 .then((result) => {8 // Revisamos si encontró el documento9 result10 // Si fue encontramos lo enviamos como respuesta11 ? res.send(result)12 // Si no fue encontrado enviamos un error 40413 : res.code(404).send({14 statusCode: 404,15 error: 'Not Found',16 message: 'Task not found with given id',17 });18 })19 .catch((error) => {20 console.error(error);2122 res.code(400).send({23 statusCode: 400,24 error: 'Bad request',25 });26 });27}
Añadir una tarea
Para añadir una tarea en muy importante especificar el método POST en la ruta.
1app.post('/tasks', addTask)
Luego de hacer eso, podemos hacer nuestro controlador.
1const addTask = (req, res) => {2 // Extraemos el contenido y si la tarea fue completada del cuerpo de la solicitud3 const { content, done } = req.body45 // Creamos un objeto con esa información6 const newTask = { content, done }78 // Dispondremos del método create para insertar una nueva tarea9 // a la base de datos, debemos pasarle el objeto recién creado10 Task.create(newTask)11 // Si fue creado exitosamente mandamos una respuesta con el12 // código 201 y el mensaje de creado13 .then(() => {14 res.code(201).send({15 statusCode: 201,16 message: 'Created',17 })18 })19 .catch((error) => {20 console.error(error)2122 res.code(400).send({23 statusCode: 400,24 error: 'Bad request',25 })26 })27}
Eliminar tarea
El proceso será similar al de obtener una tarea con su id pero especificando los métodos para borrar.
En la ruta debemos usar el método delete.
1app.delete('/tasks/:id', deleteTask)
Emplearemos el método findByIdAndDelete, este buscará la tarea y si la encuentra la borrar y nos devolverá el documento de la tarea
1const deleteTask = (req, res) => {2 const { id } = req.params34 Task.findByIdAndDelete(id)5 .then((result) =>6 result7 ? res.send({8 statusCode: 200,9 message: 'Deleted',10 })11 : res.code(404).send({12 statusCode: 404,13 error: 'Not Found',14 message: 'Task not found',15 })16 )17 .catch((error) => {18 console.error(error)1920 res.code(400).send({21 statusCode: 400,22 error: 'Bad request',23 })24 })25}
Editar tarea
Y como último editar, aquí tendremos que extraer el id de los parámetros como los datos que lleguen del cuerpo de la solicitud, usaremos el metodo PUT.
1app.put('/tasks/:id', editTask)
1const editTask = (req, res) => {2 // Extraemos el id, el content y el done de la solicitud3 const { id } = req.params4 const { content, done } = req.body56 // Creamos el objeto con los datos editados7 const editedTask = { content, done }89 // Le pasamos el id y el objeto con los nuevos datos10 Task.findByIdAndUpdate(id, editedTask)11 .then((result) => {12 result13 ? res.send({14 statusCode: 200,15 message: 'Edited',16 })17 : res.code(404).send({18 statusCode: 404,19 error: 'Not Found',20 message: 'Task not found with given id',21 })22 })23 .catch((error) => {24 console.error(error)2526 res.code(400).send({27 statusCode: 400,28 error: 'Bad request',29 })30 })31}
Establecer un error 404 modificado
Para añadir un error 404 debemos usar setNotFoundHandler y configurar la respuesta que queramos.
1app.setNotFoundHandler((req, res) => {2 res.code(404).send({3 statusCode: 404,4 error: 'Not Found',5 });6});
Fin
Hemos llegado al final, con esto podemos hacer un crud conectado a mongodb con fastify, es un framework sencillo de usar y con gran cantidad de características.