Para obtener parámetros de la URL usas el decorador @Params
@Get('products/:productId')
getProduct(@Param('productId') productId: string) {
return `product ${productId}`;
}
Introducción a NestJS
¿Qué es NestJS?
Crea tu primer proyecto con NestJS
Estructura de aplicaciones en NestJS
Presentación del proyecto: Platzi Store
Repaso a TypeScript: tipos y POO
REST API
Introducción a controladores
GET: cómo recibir parámetros
GET: parámetros query
Separación de responsabilidades
Instalación de Postman o Insomnia
Qué es el método POST
Métodos PUT y DELETE para editar y eliminar
Códigos de estado o HTTP response status codes
Integridad de datos
Introducción a servicios: crea tu primer servicio
Implementando servicios en tu controlador
Manejo de errores con throw y NotFoundException
Introducción a pipes: usa tu primer pipe
Crea tu propio pipe
Creando Data Transfers Objects
Validando parámetros con class-validator y mapped-types
Cómo evitar parámetros incorrectos
Próximos pasos
Reto: controladores y servicios restantes
Continúa con el Curso de NestJS: Programación Modular
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Nicolas Molina
Existen diferentes tipos de endpoints que se identifican a través de los Verbos HTTP. Cada uno con un propósito determinado siguiendo el protocolo.
En particular, el verbo GET suele utilizarse para endpoints que permiten la obtención de datos como un producto o una lista de productos.
Es frecuente la necesidad de que este tipo de endpoints también reciban información dinámica en las URL como el identificador de un producto.
Para capturar estos datos en NestJS, tienes que importar el decorador Param
desde @nestjs/common
y emplearlo de la siguiente manera en tus endpoints.
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('product/:idProduct')
getProduct1(@Param() params: any): string {
return `Producto id: ${params.idProduct}`;
}
@Get('product/:idProduct')
getProduct2(@Param('idProduct') idProduct: string): string {
return `Producto id: ${idProduct}`;
}
}
Observa el decorador @Get()
que posee el nombre del endpoint seguido de un :idProduct
que identifica al parámetro dinámico. Luego puedes implementar el decorador @Param()
para capturar todos los parámetros juntos en un objeto o @Param('idProduct')
para capturar únicamente el parámetro con dicho nombre.
De esta forma, accede en un navegador a localhost:3000/product/12345
para capturar ese 12345
y posteriormente utilizarlo.
Contribución creada por: Kevin Fiorentino.
import { ..., Param } from '@nestjs/common';
...
@Controller()
export class AppController {
...
@Get('products/:productId')
getProduct(@Param('productId') productId: string) {
return `product ${productId}`;
}
@Get('categories/:id/products/:productId')
getCategory(@Param('productId') productId: string, @Param('id') id: string) {
return `product ${productId} and ${id}`;
}
}
Aportes 17
Preguntas 6
Para obtener parámetros de la URL usas el decorador @Params
@Get('products/:productId')
getProduct(@Param('productId') productId: string) {
return `product ${productId}`;
}
Otra manera de recibir más de un parámetro
@Get('categories/:categoryId/products/:productId')
getCategory(@Param() { categoryId, productId }) {
return `Product ${productId}, Category ${categoryId}`;
}
Si desean recibir un parametro y hacer una prevalidación del mismo por ejemplo que debe ser un entero. Existen los pipe (estan más adelante) y uno simple es así:
@Get('products/:id')
getProduct(
@Param(
'id',
new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }),
)
id: number,
) {
return `Product ${id}`;
}
Nota: Utiliza los plurales para tus endpoints. Ejemplo:
api.example.con/tasks/
api.example.con/users/
Para obtener parámetros de la URL usas el decorador @Param
Para obtener un parámetro:
@Get('products/:productId')
getProduct(@Param('productId') productId: string) {
return product ${productId};
}
Para obtener dos parámetros:
@Get('categories/:id/products/:productId')
getCategory(@Param('productId') productId: string, @Param('id') id: string) {
return product: ${productId} and categories: ${id};
}
Por defecto todos estos archivos se crean en services desconoco si es una buena practica pero continue realizando los ejercicios de esta manera para poner una ruta dinamica consegui que funcionara de la siquiente manera
este es el archivo app.service.ts
import { Injectable, Param } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
getNewEndpoint(): string {
return 'New endpoint';
}
getPost(@Param('PostId') PostId: string): string {
return `This action returns a #${PostId} `;
}
}
y este el archivo app.controller.ts
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
// new endpoint
@Get('new')
getNewEndpoint(): string{
return this.appService.getNewEndpoint();
}
@Get('Posts/:PostId')
getPost(@Param('PostId') PostId: string): string{
return this.appService.getPost(`${PostId}`);
}
}
Se me hace muy similar a spring 😄
Considero que es mejor escribir
@Param() parametros: any
y de esta forma obtener todos los parametros usando el punto " . " a usar un @Param() por cada parametro que se necesite.
Alguien me puede decir si mi pensar es el adecuado y de no ser asi cual sería la desventaja?
De la clase, podemos definir el acceso de algún recurso de preferencia, en nuestro caso Account
.
.
Para nuestro efecto, nuestras plataforma requiere que usuarios consuman y publiquen los blogs, por ello Account
queda perfecto para el primer recurso a trabajar.
.
En este caso, definiremos un mock para simular la información de nuestro servidor por lo que anexaremos una capa de datos para poder generalizar nuestras colecciones.
.
ℹ️ Definición
Mock, en software se define como una representación de información que podemos manipular, ya sea para la generación de pruebas como la gestión casos de usos.
.
.
.
.
Para la generación de volumen de información, uso Mockaroo. Con ella, podemos minar varios casos de uso a través de su definición dejando a tu criterio su definición.
.
En mi caso, definiré mi información de la siguiente manera:
Nota. En mi caso defino mi DB con nomenclatura de Prisma para posteriormente desarrollar el schema para dicho ORM.
.
Quedando mi lote de información de la siguiente forma:
// db/mocks/account.mock.ts
import { Account } from '@entities/account.entity'
export default [
{
id: 1,
name: 'Gratiana Cluley',
email: '[email protected]',
password: 'dj61lZ',
bio: 'cursus urna ut tellus nulla',
active: true,
role: 'ADMIN',
},
]
Y mi entidad de la siguiente forma:
// entities/account.entity.ts
export interface IAccount {
id: number
name: string
email: string
password: string
bio: string
active: boolean
role: string | 'ADMIN' | 'USER'
createdAt?: Date | string
updatedAt?: Date | string
}
export type Account = IAccount
Nota. Recomiendo la generación de interfaces (estructuras de alto orden o firmas entre componentes) y tipos (generación de recursos interporables) para el tener un mejor control de recursos en TS
.
Siendo prácticos, muchos desarrolladores prefieren el uso de un recurso como plurales para después determinar el acceso, por atributos primarios o únicos como id
, de recursos individuales.
.
Sin embargo, tiende a ser muy caótico el efecto ya que abstraer recursos, plurales e individuales, preferible en 2 archivos para su desarrollo (Accounts
y Account
) .
.
Por ello, empezaremos creando nuestro servicio:
// services/account.service.ts
import { Injectable } from '@nestjs/common'
import Accounts from '@db/mocks/account.mock'
import { Account } from '@entities/account.entity'
@Injectable()
export class AccountService {
/**
* @description Find all accounts registered.
* @return Account[] */
findAccounts(): Account[] {
return Accounts
}
/**
* @description Find an account registered if exists.
* @return Account | undefined */
findAccount(id: number): Account | undefined {
return Accounts.find((account) => account.id === id)
}
}
Después, definimos nuestros controladores que mediaran la lógica del acceso a nuestro servicio:
// controllers/accounts.controller
import { Controller, Get } from '@nestjs/common'
import { AccountService } from '@services/account.service'
@Controller('accounts')
export class AccountsController {
constructor(private readonly accountService: AccountService) {}
/**
* @description Find all accounts registered.
* @return Account[] */
@Get()
getAccounts() {
return this.accountService.findAccounts()
}
}
// controllers/account.controller
import { Controller, Get } from '@nestjs/common'
import { AccountService } from '@services/account.service'
@Controller('account')
export class AccountController {
constructor(private readonly accountService: AccountService) {}
@Get()
getAccount() {
return this.accountService.findAccount(1)
}
}
Nota. Si desea que todo el ruteo quede sobre un mismo recurso utilice el prefijo en el decorador @Controller para agruparlos sobre una misma ruta, por ejemplo
@Controller('accounts')
en los controladores que desee 📚 Documentación
.
Por último, damos de alta nuestros recursos sobre el módulo principal de nuestro servidor:
// modules/server.module.ts
import { Module } from '@nestjs/common'
import { IndexController } from '@controllers/index.controller'
import { AccountsController } from '@controllers/accounts.controller'
import { AccountController } from '@controllers/account.controller'
import { IndexService } from '@services/index.service'
import { AccountService } from '@services/account.service'
@Module({
imports: [],
controllers: [IndexController, AccountsController, AccountController],
providers: [IndexService, AccountService],
})
export class ServerModule {}
.
no combinar los Verbos HTTP. con el nombre de el endpoint, es decir no colocar nunca el verbo en el nombre como /getproducts no importa sea el método debe llamarse igual q el controlador en plural.
Nota mental => Usar plurales para endpoints
Ejemplo con 2 parametros
Decorador @get y @Param
buenas practicas en REST API
Explica muy bien el profe.
👏
Excelente clase.
Excelente clase, epa ya iba a preguntar por los query, a por ello…
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?