Construir un API REST con NodeJS (Tercera parte)

Construir un API REST con NodeJS - Tercera parteEste artículo es la tercera parte del articulo original (Segunda parte), en la cual hablamos de los HTTP Verbs, su importancia, funcionalidad y cómo implementarla en nuestro API utilizando NodeJS + Express. En esta tercera parte, hablaremos acerca de los URL paths, cómo es posible crear URL parametrizadas y la forma de recuperar los parámetros del objeto request.

URL Paths

Uno de los aspectos más importantes de un servicio REST, es su URL, primero que nada, porque es la forma en que podemos consumir el servicio, pero también es importante por le da al usuario una pista significativa acerca de su funcionalidad. Una URL bien definida, podría decirle al usuario para que sirve con una precisión muy acertada, sin tener que recurrir a la documentación.

Para que una URL tenga un significado real, es necesario complementarlo con método (o verb) al que responde, pues el método nos dice el tipo de operación que va a realizar, mientras que la URL nos dice que es lo que va hacer. Analicemos las siguientes URL:

GET/users/oscar/avatar
PUT/users/oscar/avatar
DELETE/users/oscar
POST/users

Quiero que te tomes solo un momento para analizar las URL anteriores… te aseguro que sin ser un experto pudiste adivinar con gran certeza que hace cada una de estas operaciones. Si no, te recomiendo ver la segunda parte de este artículo para refrescar un poco la memoria.

Como sea, vamos a explicar que hace cada una, en la primera URL, sabemos que el GET se utiliza para consultas y la URL habla de usuarios, luego un nombre y finalmente un avatar, por lo que podemos deducir que este servicio está realizando la consulta del Avatar del usuario oscar, ¿vez que fácil?

En la segunda URL, sabemos que PUT se utiliza para realizar updates, por lo tanto, le estamos diciendo que actualice el Avatar del usuario oscar.

En la tercera URL, sabemos que DELETE se utiliza para borrar un registro, por lo que está de más decir que lo que hace es borrar el usuario oscar.

En la cuarta URL, sabemos que POST se utiliza para crear un nuevo registro y está invocando solamente /users, esto me dice que el servicio está creando un nuevo usuario.

Con Express es realmente fácil implementar estas URL, tan solo hay que definir los Routers con el método adecuado y con el URL al que debe procesar, veamos cómo quedaría:

app.get('/users/oscar/avatar', (req, res) => {
  res.send('Hello GET:/users/oscar/avatar')
})

app.put('/users/oscar/avatar', (req, res) => {
  res.send('Hello PUT:/users/oscar/avatar')
})

app.delete('/users/oscar', (req, res) => {
  res.send('Hello DELETE:/users/oscar')
})

app.post('/users', (req, res) => {
  res.send('Hello POST:/users')
})

Los paths siempre deben de representar exactamente lo que hacen, y el método debe de corresponder con la acción que realizará, pues no hacerlo, puede confundir a los desarrolladores.

Prioridad de los paths

Un error al momento de iniciar con Express es pensar que el orden en que se definen los Routers es irrelevante, como si de una función se tratara, la cual puede ser llamada desde donde sea y siempre se ejecuta la correcta, sin embargo, esto no es cierto. Por este motivo, Express evaluar los Router en el orden en que están definidos.

Existe ocasiones en que más de una URL puede colisionar y entrar en el Path equivocado, por ejemplo, las siguientes dos URL:

GET: /*

GET:/login

La primera acepta cualquier URL, porque tiene un comodín (*), mientras que la segunda, solo acepta la URL /login. En este caso, como /* esta primero, entonces atenderá las peticiones que lleguen a /login, porque el path /* cumple con el patrón, en tal caso, tendríamos que invertir el orden de los Routers de la siguiente manera:

GET:/login

GET: /*

De esta forma, cuando llegue una petición a /login, la tomará el primer Router y para todos los demás path será /* quien procese la solicitud.

URL Params

Una de las características de REST, es la posibilidad de convertir ciertas partes de una URL en parámetro, de tal forma que nos ahorra tener que escribir una URL para cada registro que necesitemos.

Regresando al ejemplo de los servicios para usuarios GET: /users/oscar, podemos apreciar que “oscar” esta fija en la URL, lo que provocaría que tuviéramos que tener un Router para cada usuario registrado. Por suerte, Express nos permite escribir URL Params. Para convertir una sección de la URL en URL param, solo tendremos que anteponer dos puntos (:) antes, por ejemplo:

/users/:username

/users/:username/:field

En la primera URL podríamos recibir consultas para todos los usuarios, por ejemplo:

/users/oscar , /users/juan , /users/pedro

Mientras que en la segunda URL podríamos consultar cualquier campo del usuario, por ejemplo:

/users/oscar/avatar  o /users/juan/banner

Para recuperar los URL Params, tan solo es necesario recuperarlos del objeto request de la siguiente manera: req.params.<name>. Veamos algunos ejemplos:

API REST - URL Params

Query params

Los query params son lo más conocidas, y son todos aquellos que van al final de la URL seguido del símbolo de interrogación (?). Se pueden enviar cuantos Query params se requiere, siempre y cuando no excedamos el límite máximo de caracteres para un URL. Cada parámetro deberá está separado un el símbolo de ampersand (&). Algunos ejemplos:

/cources?coupon=FREE&Source=Google

Este tipo de parámetros es muy común en campañas publicitarias, pues el param coupon determina que el curso a comprar es gratis (free), mientras que el param Source nos dice de donde llego el cliente (google).

Para recuperar un Query param en Express se usa la siguiente sentencia, req.query.<parama-name>. Veamos cómo implementarlo en Express.

app.get('/cources', (req, res) => {
  var coupon = req.query.coupon
  var source = req.query.source
  res.send("Coupo: " + coupon + ", Source: " + source)
})

Si ejecutamos la URL /cources?coupon=FREE&Source=Google  obtendremos el siguiente resultado:

API REST - query params

¿Te gustaría aprender las técnicas más avanzadas para crear API REST con NodeJS? Te invito a que veas mi libro “Aplicaciones reactivas con React, NodeJS & MongoDB”, donde aprenderás a crear una API REST completo, desde exponer los servicios hasta habilitar la seguridad con JSON Web Token (JTW)

Body params

El tercer y último tipo de parámetro que podemos enviarle a un servicio REST, es el payload (o body), el cual puede ser un mensaje largo que no se puede ver a simple vista. No todos los métodos HTTP soportan el envío de un payload, por lo que hay que tener eso en cuenta.

De los métodos más utilizados que soportan el envío de un payload son: POST, PUT, PATCH, DELETE. Observa que el método GET no lo soporta.

Recuperar el body del request no está simple como parecería, pues en realidad, este parámetro es un InputStream, lo que quiere decir, que se recibe como los datos poco a poco y no todo de una. Esto nos obliga a procesar el payload a medida que va llegando. Este proceso lo podemos simplificar con ayuda del módulo body-parser, el cual instalamos en la primera parte de este artículo (npm install –save body-parser).

Mediante este módulo, es posible convertir el payload en varios formatos, pero el que nos interesa es JSON, pues es el estándar para REST. Configurarlo, solo tendremos que importarlo y agregar un middleware (los analizaremos más adelante).

API REST - Body param

Finalmente, existe una última forma de recibir información para el API, la cual es a través de Header, sin embargo, esta parte la dejaremos para la siguiente parte, en la cual hablaremos de la autenticación mediante JSON Web Tokens (JWT).

16 thoughts to “Construir un API REST con NodeJS (Tercera parte)”

  1. Excelente paso a paso de construccion REST API. Les pido su amable colaboracion con el siguiente apunte:
    tengo entendido que en un proyecto que involucra Frontend, API REST y BD, los tres pueden hospedarse en servidores separados. En un proyecto que estoy construyendo, los tres mencionados los tengo en el mismo servidor. Para la prueba en mi PC me funciona la API simple ejecucion en consola de “node apirest.js”, y frontend en el navegador. Pero para publicar en un servidor remoto no encuentro forma de arrancar la API. Le he construido un componente a manera de aplicacion en Angular pero no logro hacerlo funcionar. Puede darme ideas. Gracias por la valiosa colaboracion.

    1. Hola Gilberto,
      Lo que mencionas es correcto, los 3 componentes pueden estar en servidores independientes, todo dependerá de que arquitectura de servidores que funcione mejor, de la misma forma, puede tener los 3 juntos.
      Con respecto a por que no te funciona en el servidor remoto, bueno… puede hacer cientos de motivos por el cual no funcione, y es imposible decirte sin saber nada del error que te lanza al ejecutarlo.
      saludos.

  2. Entendido Oscar, seguro no fui especifico en la pregunta. Me refiero puntuamente a la forma de inicializar la API; si localmente la puedo ejecutar con el comando node apirest.js, remotamente como lo haria?. En mi PC tengo instalado node, en el servidor remoto y teniendo en cuenta que es un hosting rentado, que necesitaria?. Definitivamente debe hacerse con un html? o conoce alguna otra forma de inicializar la api?
    Gracias

    1. Es que no existe una estructura correcta, es por eso la diferencia en muchas páginas, mi sugerencia es que organices los archivos como mejor te acomode

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *