35. Obtener un carro por ID

 

 directorios que se están usando en el ejemplo:

Copy
Download
src/
│
├── cars/
│   ├── cars.controller.ts   # Controlador (maneja las rutas HTTP)
│   ├── cars.module.ts       # Módulo (registra controlador y servicio)
│   └── cars.service.ts      # Servicio (lógica de negocio)
│
├── app.module.ts            # Módulo principal de la aplicación
└── main.ts                  # Punto de entrada (configuración de NestJS)

Explicación breve:

  • cars/: Contiene los archivos específicos del recurso Cars (controlador, módulo y servicio).

  • app.module.ts: Importa y organiza los módulos de la aplicación (en este caso, CarsModule).

  • main.ts: Inicia la aplicación y configura el servidor.

Esta estructura sigue las buenas prácticas de NestJS, separando responsabilidades en capas claras.

Cómo Obtener un Carro por ID en NestJS

En este tutorial, aprenderemos a crear un endpoint en NestJS que nos permita obtener un carro específico por su ID. Utilizaremos decoradores para manejar parámetros de la solicitud y exploraremos buenas prácticas para validar datos.

Paso 1: Estructura Inicial del Controlador

Comenzamos con un controlador básico que maneja una lista de carros:

typescript

import { Controller, Get } from '@nestjs/common';


@Controller('cars')

export class CarsController {

  private cars = ['Toyota', 'Honda', 'Jeep']; // Datos de ejemplo


  @Get()

  getAllCars() {

    return this.cars;

  }

}

  • Ruta base: /cars (retorna todos los carros).

Paso 2: Crear el Endpoint para Obtener un Carro por ID

Queremos buscar un carro usando su índice (ejemplo: /cars/1 para obtener 'Honda').

Versión Inicial (Problema)

typescript

@Get(':id')

getCarById(id) {

  console.log({ id }); // Muestra `undefined`

  return { id };

}

Issue: El parámetro id no se captura automáticamente.

Solución: Usar el Decorador @Param

NestJS requiere decoradores para extraer información de la solicitud. En este caso, usamos @Param:

typescript

import { Param } from '@nestjs/common';


@Get(':id')

getCarById(@Param('id') id: string) {

  console.log({ id }); // Ahora muestra el ID correcto

  return this.cars[+id]; // Conversión a número para acceder al arreglo

}

  • @Param('id'): Extrae el valor dinámico de la URL.

  • Tipo de dato: Por defecto, los parámetros de ruta son string.

Paso 3: Validaciones y Manejo de Errores

Actualmente, si el ID no existe (ejemplo: /cars/99), el endpoint retorna undefined con un código 200 (éxito). Esto no es ideal.

Mejora Práctica (Manejo de errores)

typescript

@Get(':id')

getCarById(@Param('id') id: string) {

  const car = this.cars[+id];

  if (!car) {

    throw new NotFoundException(`Car with ID ${id} not found`);

  }

  return car;

}

  • NotFoundException: Retorna un código 404 si el carro no existe.

  • Mensaje claro: Ayuda al cliente a entender el error.

Paso 4: Refactorización (Opcional)

Para escalabilidad, es recomendable mover la lista de carros a un servicio dedicado. Sin embargo, esto lo cubriremos en futuros tutoriales.

Conclusión

  • Decoradores clave: Usa @Param para extraer parámetros de la URL.

  • Tipado: Aunque los parámetros son string, puedes convertirlos según necesites.

  • Manejo de errores: Siempre valida y retorna respuestas HTTP adecuadas.

Ejemplo Final

typescript

@Get(':id')

getCarById(@Param('id') id: string) {

  const index = +id; // Conversión a número

  if (isNaN(index) || index < 0 || index >= this.cars.length) {

    throw new NotFoundException('Invalid car ID');

  }

  return this.cars[index];

}

Prueba en Postman:

  • GET /cars/1'Honda'

  • GET /cars/99404 Not Found

En próximos posts, exploraremos cómo usar servicios (Providers) y bases de datos. ¡Déjanos tus dudas en los comentarios!


Comentarios

Entradas más populares de este blog

48. ValidationPipe - Class Validator y Class Transformer

32-Modulos

49. Pipes Globales - A nivel de Aplicación