No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

GET: cómo recibir parámetros

7/23
Recursos

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.

Obtención de datos con GET

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

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

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}`);
  }

}

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?

Se me hace muy similar a spring 😄

Definición de Recursos

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.

.


.

ⴵ Repositorio GitHub: Vizualla

Commit: ✨ Added account resource

.


.

Account Model

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

.

Account Resource

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…