ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ отвСтствСнны Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ входящий запросов ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ.

ЦСль ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° - ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ запросов. ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠ°ΠΊΠΎΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ запрос. Π§Π°Ρ‰Π΅ всСго ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ содСрТат Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‚ Π·Π° Ρ€Π°Π·Π½Ρ‹Π΅ дСйствия.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π±Ρ‹Π·ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ класса. Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ‚Ρ‹ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ Π² класс Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΌΠ΅Ρ‚Π° Π΄Π°Π½Π½Ρ‹Π΅ для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Nest смог построит ΠΊΠ°Ρ€Ρ‚Ρƒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² (ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ запросы ΠΊ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°ΠΌ).

ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΡ#

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΌΡƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Controller() Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ для опрСдСлСния Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°. ΠœΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ прСфикс ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° - cats. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° прСфикса ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Controller() позволяСт Π»Π΅Π³ΠΊΠΎ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ связанныС ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ ΠΈ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ дублирования ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰Π΅Π³ΠΎΡΡ ΠΊΠΎΠ΄Π°. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°Π±ΠΎΡ€ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠ΅ Π·Π° взаимодСйствиС с ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒΡŽ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ с прСфиксом /customers Ρ‡Ρ‚ΠΎ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ нас ΠΎΡ‚ повторСния этого прСфикса Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅ этого ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°.

cats.controller.ts
JS TS
TypeScript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
TypeScript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
Π—Π°ΠΌΠ΅Ρ‚ΠΊΠ° Для создания ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ CLI просто Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ эту ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ $ nest g controller cats.

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ HTTP Π³Π»Π°Π³ΠΎΠ»Π° @Get() ΠΏΠ΅Ρ€Π΅Π΄ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ findAll() Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΡƒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π΅Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚Π°. Π­Ρ‚ΠΎΡ‚ Π΅Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚ соотвСтствуСт HTTP Π³Π»Π°Π³ΠΎΠ»Ρƒ (Π² Π΄Π°Π½Π½ΠΎΠΌ случаСС - GET) ΠΈ ΠΏΡƒΡ‚ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°. Π§Ρ‚ΠΎ ΠΆΠ΅ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΡƒΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°? ΠŸΡƒΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° опрСдСляСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ конкатСнирования прСфикса Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ @Controller(<path_prefix>) ΠΈ ΠΏΡƒΡ‚ΠΈ Π·Π°Π΄Π°Π½Π½ΠΎΠΌ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ запроса. БСйчас Ρƒ нас Π·Π°Π΄Π°Π½ прСфикс cats для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΠΈ Π½Π΅ Π·Π°Π΄Π°Π½Π½ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΏΡƒΡ‚ΠΈ Π² @Get() Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅, Nest сопоставит ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ этого ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° с GET /cats запросом. Как Π±Ρ‹Π»ΠΎ ΡƒΠΆΠ΅ упомянуто, ΠΏΡƒΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° содСрТит содСрТит Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ прСфикс ΠΏΡƒΡ‚ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΈ строку ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° запроса. Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, прСфикс ΠΏΡƒΡ‚ΠΈ customers совмСщСнный с Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ @Get('profile') создаст ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ сопоставлСнный с запросом GET /customers/profile.

Π’ нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²Ρ‹ΡˆΠ΅, ΠΊΠΎΠ³Π΄Π° происходит GET запрос Π½Π° этот Π΅Π½Π΄ΠΏΠΎΠΈΠ½Ρ‚, Nest направляСт запрос Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ findAll(). Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ имя ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ΅. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ для привязки ΠΊ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρƒ, Π½ΠΎ Nest Π½Π΅ ΠΏΡ€Π΅Π΄Π°Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ значСния Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΌΡƒ ΠΈΠΌΠ΅Π½ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Π΅Ρ€Π½Π΅Ρ‚ ΠΎΡ‚Π²Π΅Ρ‚ со статусом 200 ΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½Ρ‹ ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ случаС это просто строка. ΠŸΠΎΡ‡Π΅ΠΌΡƒ Ρ‚Π°ΠΊ происходит? Для объяснСния этого ΠΌΡ‹ сначала познакомимся с ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠ΅ΠΉ Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ Nest ΠΈΠΌΠ΅Π΅Ρ‚ 2 Ρ€Π°Π·Π½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов:

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹ΠΉ (рСкомСндуСтся) ИспользованиС этого Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ запроса Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ JavaScript ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π»ΠΈΠ±ΠΎ массив, Ρ‚ΠΎ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ»ΠΈ массив Π±ΡƒΠ΄Π΅Ρ‚ автоматичСски сСриализован Π² JSON. А ΠΊΠΎΠ³Π΄Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹ΠΉ JavaScript Ρ‚ΠΈΠΏ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ string, number, boolean) Nest Π½Π΅ станСт ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π° просто Π΅Π³ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚. Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ запросов ΠΎΡ‡Π΅Π½ΡŒ простой: просто Π²Π΅Ρ€Π½ΠΈΡ‚Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° ΠΎΠ± ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΌ позаботится Nest.

Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, status code ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ всСгда 200, ΠΊΡ€ΠΎΠΌΠ΅ POST запросов для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ 201. ΠœΡ‹ ΠΎΡ‡Π΅Π½ΡŒ просто ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ² @HttpCode(...) Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Π½Π°Π΄ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ (смотри Код статуса)
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎ зависимый ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Express), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Π½Π΅Π΄Ρ€Π΅Π½ Π² Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @Res() (ΠΏΡ€ΠΈΠΌΠ΅Ρ€: findAll(@Res() response)). Π‘ Ρ‚Π°ΠΊΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ Ρƒ вас появляСтся Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ (Π° Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΎΡ‚Π²Π΅Ρ‚ΡΠ²Ρ‚Π΅Π½Π½ΠΎΡΡ‚ΡŒ) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ собствСнныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов прСдоставляСмыС этим ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ. К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Express Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄ для ΠΎΡ‚Π²Π΅Ρ‚Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° response.status(200).send().
ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° сразу. Nest ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ @Res() Π»ΠΈΠ±ΠΎ @Next() Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹. Если ΠΎΠ±Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ сразу, Ρ‚ΠΎ стандартный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ автоматичСски Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡΡ для Ρ‚ΠΎΠ³ΠΎ этого ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΈ большС Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ оТидалось.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ запроса#

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ часто Π½ΡƒΠΆΠ΄Π°ΡŽΡ‚ΡΡ Π² дСталях клиСнтского запроса. Nest прСдоставляСт доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ запроса ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ которая ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Express). ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ запроса проинструктировав Nest Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΠ² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Req() Π² сигнатуру ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.

cats.controller.ts
JS TS
TypeScript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
TypeScript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
Подсказка Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ express (ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²Ρ‹ΡˆΠ΅ request: Request), установитС ΠΏΠ°ΠΊΠ΅Ρ‚ @types/express.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚ запроса прСдставляСт собой HTTP-запрос ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ свойства строки запроса, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², HTTP Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ², ΠΈ Ρ‚Π΅Π»Π° (ΡƒΠ·Π½Π°Ρ‚ΡŒ большС здСсь). Π’ Π±ΠΎΠ»ΡŒΡˆΠ΅Π½ΡΡ‚Π²Π΅ случаСв Π½Π΅Ρ‚ нСобходимости ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ эти свойства Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ. ВмСсто этого ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ наши Π»ΡŽΠ±ΠΈΠΌΡ‹Π΅ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ @Body() ΠΈΠ»ΠΈ @Query, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ доступны ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ. НиТС Π΅ΡΡ‚ΡŒ список Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈ простых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ для ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹.

@Request()req
@Response(), @Res()*res
@Next()next
@Session()req.session
@Param(key?: string)req.params / req.params[key]
@Body(key?: string)req.body / req.body[key]
@Query(key?: string)req.query / req.query[key]
@Headers(name?: string)req.headers / req.headers[name]
@Ip()req.ip

* Для совмСстимости с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ (Express ΠΈΠ»ΠΈ Fastify), Nest прСдоставляСт Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ @Res() ΠΈ @Response(). @Res() это просто алиса для @Response(). Оба ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ response ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹. Π’ΠΎ врСмя ΠΈΡ… использования Ρ‚Π°ΠΊ ΠΆΠ΅ стоит ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ для ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΌΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ (ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ @types/express) для получСния Π±ΠΎΠ»ΡŒΡˆΠΈΡ… прСимущСств. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ @Res() ΠΈΠ»ΠΈ @Response() Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅, Π²Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚Π΅ Nest Π² Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎ зависимый Ρ€Π΅ΠΆΠΈΠΌ для этого ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, ΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚Π΅ΡΡŒ отвСтствСнным Π·Π° ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΡƒ ΠΎΡ‚Π²Π΅Ρ‚Π°. Когда Π²Ρ‹ Ρ‚Π°ΠΊ Π΄Π΅Π»Π°Π΅Ρ‚Π΅, Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ запрос сдСлав Π²Ρ‹Π·ΠΎΠ² Π½Π° response ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ (ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ res.json(...) ΠΈΠ»ΠΈ res.send(...)), Π»ΠΈΠ±ΠΎ сСрвСр Π΄ΠΎΠ»ΠΆΠ΅Π½ это ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ.

Подсказка Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ кастомныС Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ ΠΊ этой Π³Π»Π°Π²Π΅.

РСсурсы#

Π Π°Π½Π΅Π΅, ΠΌΡ‹ объявили эндпоинт для получСния ΠΊΠΎΡ‚ΠΎΠ² (GET route). ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ эндпоинт для создания Π½ΠΎΠ²Ρ‹Ρ… записСй. Для этого Π΄Π°Π²Π°ΠΉΡ‚Π΅ создадим POST ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ:

cats.controller.ts
JS TS
TypeScript

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

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
TypeScript

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

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}

Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ просто. Nest прСдоставляСт Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ‚Ρ‹ для стандартных HTTP Π³Π»Π°Π³ΠΎΠ»ΠΎΠ² @Put(), @Delete(), @Patch(), @Options(), @Head(), and @All().

ΠŸΠΎΠ΄ΡΡ‚Π°Π½ΠΎΠ²ΠΎΡ‡Ρ‚Π½Ρ‹Π΅ Π·Π½Π°ΠΊΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ²#

Nest ΠΈΠΌΠ΅Π΅Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ². НапримСр, Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² качСствС подстановочного Π·Π½Π°ΠΊΠ° ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ любой ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ символов.

TypeScript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}

ΠŸΡƒΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° 'ab*cd' Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΠΎΠ²Π°Ρ‚ΡŒ abcd, ab_cd, abecd ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅. Π‘ΠΈΠΌΠ²ΠΎΠ»Ρ‹ ?, +, *, and () ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹ Π² ΠΏΡƒΡ‚ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ подмноТСствами ΠΈΡ… эквивалСнтов ΠΈΠ· рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ. ДСфис (-) ΠΈ Ρ‚ΠΎΡ‡ΠΊΠ° (.) ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ путями Π½Π° остовС строк. (The hyphen ( -) and the dot (.) are interpreted literally by string-based paths.).

Бтатус ΠΊΠΎΠ΄#

Как ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, статус ΠΊΠΎΠ΄ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ всСгда 200, ΠΊΡ€ΠΎΠΌΠ΅ POST запросов Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ 201. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΎΡ‡Π΅Π½ΡŒ просто Π΄ΠΎΠ±Π°Π²ΠΈΠ² @HttpCode Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.

TypeScript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
Подсказка Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ HttpCode ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° @nestjs/common.

Часто, статус ΠΊΠΎΠ΄ Π½Π΅ статичСский, Π° зависит ΠΎΡ‚ ΠΊΠ°ΠΊΠΈΡ… Π»ΠΈΠ±ΠΎ Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΎΠ². Π’ этом случаС, Π²Ρ‹ ΠΌΠΎΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ respnose (ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Res()) ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (Π»ΠΈΠ±ΠΎ, Π² случаС Ссли это ошибка, Π²Ρ‹Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅).

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ#

Для установлСния Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Header() Π»ΠΈΠ±ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ response (ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ res.header() Π½Π° ΠΏΡ€ΡΠΌΡƒΡŽ).

TypeScript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
Подсказка Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ Header ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° @nestjs/common.

ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅#

Для пСрСнаправлСния ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ URL, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·Π²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Redirect() Π»ΠΈΠ±ΠΎ response ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (Π²Ρ‹Π·Π²Π°Π² res.redirect() Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ).

@Redirect() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ url ΠΈ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ statusCode. АргумСнт statuCode ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 302 (Found) Ссли Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½

TypeScript

@Get()
@Redirect('https://nestjs.com', 301)

Иногда Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Ρ…ΠΎΡ‚Π΅Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ HTTP статус ΠΊΠΎΠ΄ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ URL динамичСски. Π”Π΅Π»Π°ΠΉΡ‚Π΅ это возвращая ΠΈΠ· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹:

JSON

{
  "url": string,
  "statusCode": number
}

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния пСрСопрСдСлят Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π΅Π½Π½Ρ‹Π΅ Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Redirect(). К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ:

TypeScript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°#

ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ со стачичСским ΠΏΡƒΡ‚Π΅ΠΌ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ динамичСскиС Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ запроса (ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ GET /cats/ для получСния ΠΊΠΎΡ‚Π° с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ Π°ΠΉΠ΄ΠΈ Ρ€Π°Π²Π½Ρ‹ΠΌ 1). Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ ΠΏΠ°Ρ‚Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° Π² ΠΏΡƒΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° для получСния динамичСского значСния для этой ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ URLa запроса. Π’ΠΎΠΊΠ΅Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ @Get() Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½ΠΈΠΆΠ΅ дСмонстрируСт ΠΊΠ°ΠΊ это ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π΅Π½Π½Ρ‹Π΅ Ρ‚Π°ΠΊΠΈΠΌ способом ΠΌΠΎΠ³ΡƒΡ‚ΡŒ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° @Param() ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² сигнатуру ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

Routes with static paths won't work when you need to accept dynamic data as part of the request (e.g., GET /cats/1 to get cat with id 1). In order to define routes with parameters, we can add route parameter tokens in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the @Get() decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the @Param() decorator, which should be added to the method signature.

JS TS
TypeScript

@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
TypeScript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}

@Param() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для дСкорирования ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° (params Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½ΠΈΠΆΠ΅), ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° доступными ΠΊΠ°ΠΊ свойства Π΄Π΅ΠΊΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅Π»Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. Как Π²ΠΈΠ΄Π½ΠΎ Π² ΠΊΠΎΠ΄Π΅ Π½ΠΈΠΆΠ΅, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ id ΡΡΡ‹Π»Π°ΡΡΡŒ Π½Π° params.id. Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€, ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρƒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° прямо ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅Π»Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. @Param() is used to decorate a method parameter (params in the example above), and makes the route parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the id parameter by referencing params.id. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

Подсказака Π˜ΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Param ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° @nestjs/common.
JS TS
TypeScript

@Get(':id')
findOne(@Param('id') id): string {
  return `This action returns a #${id} cat`;
}
TypeScript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}

Sub-Domain Routing#

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Controller ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΎΠΏΡ†ΠΈΡŽ host для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚Π΅Ρ€Π±ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎΠ±Ρ‹ HTTP host входящих запросов совпадал с ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ. The @Controller decorator can take a host option to require that the HTTP host of the incoming requests matches some specific value.

TypeScript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Fastify Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, ΠΏΡ€ΠΈ использовании субдомСнной ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Express Π°Π΄Π°ΠΏΡ‚Π΅Ρ€. ΠŸΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Since Fastify lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Π’Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ path ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°, опция host ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ для получСния динамичСского значСния ΠΈΠ· ΠΈΠΌΠ΅Π½ΠΈ хоста. Π’ΠΎΠΊΠ΅Π½ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° хоста Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ @Controller() Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½ΠΈΠΆΠ΅ дСмонстрируСт это использованиС. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ хоста ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Ρ‚Π°ΠΊΠΈΠΌ способом ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ доступны с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° HostParam(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² сигнатуру ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

Similar to a route path, the hosts option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the @Controller() decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the @HostParam() decorator, which should be added to the method signature.

TypeScript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}

ΠžΠ±Π»Π°ΡΡ‚ΡŒ примСнСния#

Для людСй ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… Π±Π΅ΠΊΠ³Ρ€Π°ΡƒΠ½Π΄ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… языков Для людСй ΠΈΠ· Ρ€Π°Π·Π½Ρ‹Ρ… языков программирования ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹ΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² Nest практичСски всС распрСдСляСтся ΠΌΠ΅ΠΆΠ΄Ρƒ входящими запросами. Π£ нас Π΅ΡΡ‚ΡŒ ΠΏΡƒΠ» соСдинСний с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…, синглтон сСрвисы с Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ состояниСм ΠΈ Ρ‚.Π΄. Π—Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Node.js Π½Π΅ слСдуСт ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ запрос/ΠΎΡ‚Π²Π΅Ρ‚ Π±Π΅Π· сохранСния состояния, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос обрабатываСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, использованиС синглтон экзСмпляров ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒ бСзопасно для Π½Π°ΡˆΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully safe for our applications.

Однако ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΏΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π½Ρ‹Π΅ случаи ΠΊΠΎΠ³Π΄Π° основанноС Π½Π° запросС врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос Π² GraphQL ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, отслСТиваниС запроса ΠΈΠ»ΠΈ multi-tenancy. Π£Π·Π½Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΊΠΎΡ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ примСнСния ΠΌΠΎΠΆΠ½ΠΎ здСсь.

Asynchronicity#

ΠœΡ‹ любим соврСмСнный JavaScript ΠΈ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ Ρ‡Ρ‚ΠΎ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… это Π² основном асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Nest ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с async функциями.

Подсказка Π£Π·Π½Π°ΠΉ большС ΠΎ async / await функциях здСсь

КаТдая асинхронная функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Promise. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Nest Π·Π°Ρ€Π΅Π·ΠΎΠ»Π²ΠΈΡ‚ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€: Every async function has to return a Promise. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts
JS TS
TypeScript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
TypeScript

@Get()
async findAll() {
  return [];
}

Код Π²Ρ‹ΡˆΠ΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π²Π°Π»ΠΈΠ΄Π½Ρ‹ΠΉ. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² Π² Nest Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΡ‰Π½Ρ‹Π΅, Ρ‚.ΠΊ. ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ RxJS observable streams. Nest автоматичСски ΠΏΠΎΠ΄ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ Π½Π° источник собития Π² Π²ΠΎΠ·ΡŒΠΌΠ΅Ρ‚ послСднСС эммитнутоС событиС (ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ). The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS observable streams. Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts
JS TS
TypeScript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
TypeScript

@Get()
findAll() {
  return of([]);
}

Оба ΠΈΠ· Π²Ρ‹ΡˆΠ΅ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ всС, Ρ‡Ρ‚ΠΎ соотвутствуСт вашим трСбованиям.

Request payloads#

Наш ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ POST ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Π½Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΎΡ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°. Π”Π°Π²Π°ΠΉΡ‚Π΅ исправим это Π΄ΠΎΠ±Π°Π²ΠΈΠ² @Body() Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€. Our previous example of the POST route handler didn't accept any client params. Let's fix this by adding the @Body() decorator here.

Но спСрва (Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ TypeScript), Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ DTO (Data Transfer Object) схСму. DTO это ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ опрСдСляСт Π² ΠΊΠ°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ ΠΏΠΎ сСти. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ DTO схСму ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ TypeScript интСрфСйсы, Π»ΠΈΠ±ΠΎ простой класс. Π§Ρ‚ΠΎ интСрСсно, ΠΌΡ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ классы. ΠŸΠΎΡ‡Π΅ΠΌΡƒ? ΠšΠ»Π°ΡΡΡ‹ это Ρ‡Π°ΡΡ‚ΡŒ JavaScript ES6 стандарта, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ½ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ настоящиС сущности Π² скомпилированном JavaScript. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ TypeScript интСрфСйсы ΡƒΠ΄Π°Π»Π°ΡŽΡ‚ΡΡ Π²ΠΎ врСмя транспиляции, Nest Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ Π½ΠΈΠΌ Π²ΠΎ врСмя выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π­Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» ΠΊΠ°ΠΊ Pipes ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ возмоТности ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ доступ ΠΊ ΠΌΠ΅Ρ‚Π°-Ρ‚ΠΈΠΏΡƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π²ΠΎ врСмя выполнСния. But first (if you use TypeScript), we need to determine the DTO (Data Transfer Object) schema. A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using TypeScript interfaces, or by simple classes. Interestingly, we recommend using classes here. Why? Classes are part of the JavaScript ES6 standard, and therefore they are preserved as real entities in the compiled JavaScript. On the other hand, since TypeScript interfaces are removed during the transpilation, Nest can't refer to them at runtime. This is important because features such as Pipes enable additional possibilities when they have access to the metatype of the variable at runtime.

Π”Π°Π²Π°ΠΉΡ‚Π΅ создадим CreateCatDto класс:

create-cat.dto.ts
JS TS
TypeScript

export class CreateCatDto {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}

Он ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Ρ€ΠΈ Π±Π°Π·ΠΎΠ²Ρ‹Ρ… свойства. ПослС Ρ‡Π΅Π³ΠΎ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ новосозданный DTO Π²Π½ΡƒΡ‚Ρ€ΠΈ CatsController;

cats.controller.ts
JS TS
TypeScript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
TypeScript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок#

Π•ΡΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ Π³Π»Π°Π²Π° ΠΎΠ± ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ошибок (Ρ‚.Π΅. Ρ€Π°Π±ΠΎΡ‚Π° с ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ).

Full resource sample#

НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ нСсколько доступных Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² для создания Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°. Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ прСдоставляСт Π½Π°Π±ΠΎΡ€ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² для получСния ΠΈ манипулирования Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.

cats.controller.ts
JS TS
TypeScript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(@Query() query: ListAllEntities) {
    return `This action returns all cats (limit: ${query.limit} items)`;
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
TypeScript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(@Body() createCatDto) {
    return 'This action adds a new cat';
  }

  @Get()
  @Bind(Query())
  findAll(@Query() query) {
    return `This action returns all cats (limit: ${query.limit} items)`;
  }

  @Get(':id')
  @Bind(Param('id'))
  findOne(@Param('id') id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(@Param('id') id, @Body() updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(@Param('id') id) {
    return `This action removes a #${id} cat`;
  }
}

Getting up and running#

Π₯ΠΎΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², Nest всС Π΅Ρ‰Π΅ Π½Π΅ Π·Π½Π°Π΅Ρ‚ ΠΎ сущСствовании CatsController ΠΈ ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Nest Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ экзСмпляр этого класса.

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ всСгда ΠΏΡ€Π΅Π½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ, ΠΏΠΎ этой ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ массив controllers Π² Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π΅ @Module(). Посколько ΠΌΡ‹ Π΅Ρ‰Π΅ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, ΠΊΡ€ΠΎΠΌΠ΅ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ AppModule, ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² Π½Π΅Π³ΠΎ CatsController:

app.module.ts
JS TS
TypeScript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}

ΠœΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ для класса модуля ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Module(), ΠΈ Nest c Π»Π΅Π³ΠΊΠΎΡΡ‚ΡŒΡŽ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ созданны.

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎ-зависимый ΠΏΠΎΠ΄Ρ…ΠΎΠ΄#

Π”ΠΎ сих ΠΏΠΎΡ€ ΠΌΡ‹ обсуТдали стандартный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ. Π’Ρ‚ΠΎΡ€ΠΎΠΉ способ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ это использованиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° response. Π§Ρ‚ΠΎΠ±Ρ‹ Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ response, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @Res(). Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ различия, Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ CatsController:

JS TS
TypeScript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
TypeScript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}

Π₯ΠΎΡ‚ΡŒ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΈ Π΄Π°Π΅Ρ‚ большС гибкости Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ситуация прСдоставляя ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΎΡ‚Π²Π΅Ρ‚Π° (ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ, спСцифичныС для Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ‚.Π΄), всС ΠΆΠ΅ Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ с ΠΎΡΡ‚ΠΎΡ€ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ. Π’ основном этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠ΅Π½Π΅Π΅ понятный ΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ нСдостатки. Π“Π»Π°Π²Π½Ρ‹ΠΉ нСдостаток это Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ Π²Ρ‹ тСряСтС ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ c функциями Nest ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ зависят ΠΎΡ‚ стандартной ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов Π² Nest, Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ Π˜Π½Ρ‚Π΅Ρ€Ρ†Π΅ΠΏΡ‚ΠΎΡ€Ρ‹ ΠΈ @HttpCode() Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€. Π’Π°ΠΊΠΆΠ΅ ваш ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ зависимым ΠΎΡ‚ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹ΠΉ API Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΡ‚Π²Π΅Ρ‚Π°), ΠΈ слоТнСС Π² тСстированнии (Π²Π°ΠΌ придСтся ΠΌΠΎΠΊΠ°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ запроса ΠΈ Ρ‚.Π΄.).

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ стандартный ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ всСгда Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅, Ссли это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

Support us

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more here.

Principal Sponsor

Sponsors / Partners

Become a sponsor