Veremos qué es el Query String y cómo componer rutas de la aplicación que son capaces de recibir datos en la URL (cualquier conjunto clave / valor). Explicaremos cómo recibir los datos en el controlador con el decorador @Query.
Los controladores son capaces de recibir distintas informaciones de las solicitudes que realizan los clientes. En el Manual de Nest hemos aprendido a recibir datos como parámetros en la ruta (URL) y mediante el body de la solicitud, pero hay todavía otras posibilidades por explorar.
Una de las maneras más básicas y utilizadas para recibir datos en una ruta es la denominada "query string", que básicamente consiste en enviar cualquier conjunto de datos en la URL, para que puedan ser procesados por las aplicaciones.
Qué es Query String
Query String es la típica forma con la que se envían datos en solicitudes de tipo Get, usando la misma cadena de la URL. Mediante este mecanismo podemos enviar cualquier juego de datos clave / valor, expresado en la dirección del recurso al que se accede.
Las URL que envían datos por Query String tienen esta forma:
http://example.com?dato1=valor1&dato2=valor2
En la anterior URL estaríamos mandando dos datos:
- dato1 con el valor "valor1"
- dato2 con el valor "valor2"
Enviar datos en la URL no se considera algo muy elegante, porque los datos aparecen en la misma dirección y quedan muy a la vista del usuario. Incluso podría pasar que el usuario manipule manualmente esos datos, pudiendo afectar al funcionamiento de las aplicaciones. Sin embargo tiene algunas ventajas importantes, como por ejemplo que se pueden crear enlaces profundos capaces de enviar datos desde el cliente al servidor. Esos enlaces profundos los podrías distribuir de diversos modos, por ejemplo en un email. Además se pueden guardar URLs complejas en favoritos que envían datos al servidor.
De hecho, las ventajas de usar Query String son las que hacen que servicios como Google usen ese mecanismo cuando hacemos una búsqueda con el buscador. Podemos hacer por ejemplo una búsqueda, copiar la URL y pasarla a un email o mensaje de Whatsapp, por ejemplo.
Cómo se reciben los datos del query string en los controladores Nest
Recibir los datos del query string es muy sencillo y, como podrías imaginar, se realiza mediante un decorador, en este caso @Query().
Básicamente declaramos un parámetro en el método del controlador que decoramos con @Query, tal como puedes ver a continuación.
@Get('query')
rutaQuery(@Query() query) {
return query;
}
Por supuesto, no debemos olvidarnos de importar los decoradores que usamos:
import {
Controller,
Get,
Query
} from '@nestjs/common';
Esto permitirá recibir un objeto en el parámetro "query" que tendrá todos los datos que se están enviando en la URL.
Por tanto, si nosotros componemos una URL como esta:
http://localhost:3000/query?x=24&y=xxx
El valor que se inyectará en el parámetro query será este objeto:
{
"x": "24",
"y": "xxx"
}
Dado que el parámetro query es un objeto, podemos perfectamente acceder a sus propiedades de manera precisa:
return `El dato query.x ha recibido el valor ${query.x}`;
Por supuesto, query es el nombre de un parámetro, podríamos ponerle cualquier nombre que deseemos. Obviamente, el decorador @Query() decora cualquier parámetro donde quieras recibir los datos del query string.
Cómo recibir una variable en concreto por Query String
A veces no necesitamos recibir todas las variables posibles del Query String y requerimos solamente un dato. En el decorador @Query() podemos simplemente indicar qué variable del Query String se desea recibir y Nest nos la entregará, en vez de entregarnos todo el objeto completo con todos los posibles datos enviados.
Vamos a suponer que necesitamos recibir una variable llamada "count", con una URL que tendría esta forma:
http://localhost:3000/cars?count=3
Al declarar el método del controlador podemos recibir ese dato de manera única, indicándolo en el decorador @Query() como parámetro. Sería más o menos así:
@Get('cars')
carsQuery(@Query('count') carCount: number) {
return carCount;
}
Ahora, el valor que nos llegará al parámetro "carCount" sería el enviado en la URL. Solo el dato, si es que existe.
Debes tener cuidado porque, si no se manda en la URL el dato "count", dado que hemos tipado el dato como "number", nos entregará NaN (Not a Number). Si no hubiésemos tipado carCount nos entregaría una cadena vacía.
Cómo validar un dato que llega en Query String en un método del controlador
Puede que el dato que estamos recibiendo sea esencial para el funcionamiento de la aplicación. Validar estos datos es muy sencillo en Nest gracias al uso de pipes.
Imaginemos que en la ruta anterior (cars?count=3) sea fundamental recibir la variable count y asegurarse de que es un entero. Si no lo es, entonces no queremos ejecutar nada en esa ruta, sino mandar un mensaje de error al cliente.
En este caso podemos hacer uso del pipe "ParseIntPipe" que nos proporciona el framework, que hace justamente la función de validar el dato y convertirlo al tipo number dentro del método.
No hemos visto pipes todavía y es algo importante que vamos a abordar en el manual de Nest, así que si tienes cualquier duda puedes consultar capítulos siguientes donde los veremos con detalle. De momento tenemos aquí una sencilla muestra de uso de unos pipes.
@Get('cars')
carsQuery(@Query('count', ParseIntPipe) carCount: number) {
return carCount;
}
El pipe lo tendrás que importar de @nestjs/common:
import { ParseIntPipe } from '@nestjs/common';
Ahora, si no nos pasan el dato "count" mediante el query string, o nos pasan un valor que no sea específicamente un numérico entero, la aplicación lanzará un mensaje de error automáticamente y no se ejecutará el método del controlador.
El mensaje tendrá un aspecto como este:
{
"statusCode": 400,
"message": "Validation failed (numeric string is expected)",
"error": "Bad Request"
}
Conclusión
De momento es todo lo que necesitas saber sobre cómo recibir datos enviados por la URL, mediante query string. Como puedes ver, no es muy complicado de realizar en los controladores y hasta cierto punto es muy similar a cómo recibíamos los datos de los parámetros con @Param().
A lo largo del manual de NestJS hemos dado un buen repaso a muchas de las cosas que podemos hacer con controladores en Nest. Son una de las piezas más importantes de toda aplicación con este framework, por lo que volveremos repetidas veces a ellos, pero en los siguientes artículos vamos a cambiar de tercio, para comenzar a hablar de los servicios.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...