Construyendo APIs REST utilizando Expressjs

mortegac

Manuel Ortega Carcamo

Posted on April 18, 2021

Construyendo APIs REST utilizando Expressjs

Si no sabes qué es una API REST, recomiendo leer sobre esto aquí.

A modo de breve resumen, construir una API de forma REST significa que tienes que construir sus endpoints de URL agrupados por "recursos". Un recurso es algo que quieres gestionar, por ejemplo: un estudiante, un usuario, un auto, etc. Un recurso es algo similar a una tabla de base de datos, pero los llamamos "recursos" debido a algunas excepciones.

Aquí hay un ejemplo de endpoints RESTful API para gestionar Estudiantes:

Método URL Descripción
GET /estudiante Debería devolver todos los estudiantes
GET /estudiante/1 Debería devolver un solo estudiante con el id=1
GET /cohort/1/estudiantes Debería devolver todos los estudiantes de la clase con el id=1
POST /estudiante Debería crear un nuevo estudiante
PUT /estudiante/1 Debería actualizar la información del estudiante con el id=1
DELETE /estudiante/1 Debería eliminar al estudiante con el id=1

Echa un vistazo a las URL, ellas siguen un patrón. Después de un tiempo, los endpoints hablarán por sí mismos, tendrán sentido y podrás adivinar a lo que hacen o incluso adivinar algunos endpoints. Esa es la idea.

[[info]]
| ☝️ Puede leer más sobre las API REST en esta lección de BreatheCode.
Aquí hay un video de 8 minutos que explica REST: https://www.youtube.com/watch?v=7YcW25PHnAA

Ahora hablemos sobre Expressjs

Expressjs es librería que nos permite construir un servidor web API de una forma rápida, minimalista y flexible utilizando nodejs. El primer paso para utilizarla es realizando la instalación en tu proyecto, para esto en tu terminal debes ejecutar:

$ npm install express --save
Enter fullscreen mode Exit fullscreen mode

Una vez finalizada la instalación podemos crearas un archivo server.js ya agregaremos las siguientes líneas, el computar comenzará a escuchar las solicitudes HTTP:

const express = require('express');
const app = express();

app.get('/', (req, res)=>{
    res.send("Hello World!")
})


app.listen(4000, function(){
    console.log('API en ejecución en el puerto 4000');
})
Enter fullscreen mode Exit fullscreen mode

Haz clic para probar este código en vivo.

Expressjs Hello-Wold explicado

const express = require('express'); #aquí importamos la librería Expressjs en nuestro archivo.
const app = express(); #aquí creamos una nueva instancia del servidor Expressjs.

app.get('/', (req, res)=>{  #aquí definimos el primer path de la API: GET /
    res.send("Hello World!")  #expressjs devolverá "Hello World, esto podría ser un string HTML o un string JSON.
})


app.listen(4000, function(){  #finalmente iniciamos el servidor en el localhost.
    console.log('API en ejecución en el puerto 4000');
})
Enter fullscreen mode Exit fullscreen mode

En Expressjs podemos agregar nuevos endpoints utilizando la variable app que es la instancia que definimos de expressjs y agregando el método http donde se encontrará disponible nuestro endpoint app.get('/', (req, res)=>{}, como puedes ver tendremos una función de devolución de llamada que recibirá 2 parámetros req, res. El detalle de estos parámetros es el siguiente:

  • req : Es un objeto que representa la solicitud HTTP y nos entrega información del request como el body, query params, HTTP headers.

  • res : Es un objeto que representa la respuesta HTTP que envía la aplicación Express cuando recibe una solicitud HTTP

En el siguiente link puedes acceder a la documentación de (Expressjs)[http://expressjs.com/es/api.html]

Agregando nuevos endpoints

Si deseas agregar otro endpoint a tu API que se ejecuta cuando un cliente haga el GET/person, tendrás que agregar otro bloque de código como este:

app.get('/', (req, res)=>{  #aquí definimos el primer path de la API: GET /
    res.send("Hello World!")  #expressjs devolverá "Hello World, esto podría ser un string HTML o un string JSON.
})
Enter fullscreen mode Exit fullscreen mode

Especificando el método: GET, PUT, POST, DELETE

Si deseas que tu endpoint responda a POST, PUT o DELETE, puedes especificarlo de la siguiente manera:

const express = require('express');
const app = express();

app.get('/', (req, res)=>{  #aquí definimos el primer path de la API: GET /
    res.send("Se recibió un GET")
})

app.post('/', (req, res)=>{  #aquí definimos el primer path de la API: POST /
    res.send("Se recibió un POST")
})

app.listen(4000, function(){  #finalmente iniciamos el servidor en el localhost.
    console.log('API en ejecución en el puerto 4000');
})
Enter fullscreen mode Exit fullscreen mode

Respondiendo un cuerpo JSON

La respuesta puede ser básicamente lo que quieras siempre que sea un string: HTML, JSON, CSS, imágenes, etc. Solo asegúrate de convertir en string lo que quieras responder.

En el siguiente ejemplo, estamos utilizando el método JSON.stringify para convertir un objeto llamado person1 en en un string JSON antes de devolverlo al cliente.

const express = require('express');
app.get('/person', (req, res)=>{
    const person1 = {
        "name": "Bob"
    }
    res.status(200).json(person1);
})
Enter fullscreen mode Exit fullscreen mode

El código de respuesta

El código de respuesta es 200 por defecto, y 500 si hay un error desconocido. Si deseas responder al cliente con un código diferente, deberás especificarlo así:

const express = require('express');
app.get('/person', (req, res)=>{
    const contenido = {
      "detalles": "Hubo un error en la solicitud"
    }
    res.status(400).json(contenido); # aquí cambiamos el código de estado a 400 (código muy común en caso de errores de solicitud)
})
Enter fullscreen mode Exit fullscreen mode

Manejo de errores y validaciones

Pero ¿y si la solicitud viene con errores? Por ejemplo: si tenemos un endpoint para crear una persona y debemos especificar el first_name Y el last_name, pero solo se encontró el first_name en la solicitud, así es como lo validaríamos:

const express = require('express');

app.use(express.json()) // Permite parsear el contenido en un tipo application/json
app.use(express.urlencoded({ extended: true })) // Permite parsear el contenido en un tipo application/x-www-form-urlencoded


app.post('/person', (req, res) => {
    const { body } = req; 

    if (!body) {
        return res.status(400).json({ message: "The request body is null" });
    }

    if (!body.hasOwnProperty('first_name')) {
        return res.status(400).json({ message: "The request first_name is null" });
    }

    if (!body.hasOwnProperty('last_name')) {
        return res.status(400).json({ message: "The request last_name is null" });
    }

    return res.status(400).json(body);
})
Enter fullscreen mode Exit fullscreen mode

La librería express-validator nos entrega una forma más cómoda para el manejo de las validaciones, pueden obtener más información de como usarla visitando su documentación https://express-validator

Midlewares

Un midleware es una función que tiene acceso al objeto de solicitud o request, al objeto de respuesta o response y a la siguiente función de midleware a ejecutarse en el ciclo de solictud/respuesta. Una vez que nuestro midleware termine su ejecución es importante ejecutar la función next() o la solicitud quedara colgada.

A continuación un ejemplo de un midleware que imprimirá por consola la fecha y hora en la que ocurren las consultas a la API

const express = require('express');

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();  # aquí invoca al siguiente midleware
});

Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
mortegac
Manuel Ortega Carcamo

Posted on April 18, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related