Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

Nest.js 가이드 – Nest 및 Node로 REST API 구축

Node.js 백엔드 개발자라면 기본적으로 Node.js가 매우 기본적이며 앱을 구축하는 동안 필요한 것에 대해 어떤 가정도 하지 않는다는 점에 동의할 것입니다. 결과적으로 라우팅 처리, API 호출, TypeScript 또는 웹 소켓 설정은 물론 코드 구성, 파일 구조, 명명 규칙과 같은 기본적인 사항까지 포함하여 앱 전체에서 사용하려는 모든 설정을 담당하게 됩니다. .

대규모 애플리케이션을 관리하는 것은 어려운 작업일 수 있습니다. 특히 애플리케이션이 명확한 구조와 엄격한 코드 구성 지침에 따라 설계되지 않은 경우 더욱 그렇습니다.

Nest.js는 개발자가 다른 작은 구현 세부 사항보다는 애플리케이션 문제에 집중할 수 있도록 Node.js에 대한 추상화를 생성하여 이러한 문제 중 일부를 해결하려고 합니다.

이 가이드에서는 Nest.js의 도움으로 엔터프라이즈급 Node.js 애플리케이션을 즉시 구축할 수 있도록 속도를 높이는 것을 목표로 Nest.js의 핵심 기본 사항을 위에서 아래로 학습합니다.

이 가이드를 통해 배우게 될 모든 내용은 점진적입니다. 입문 개념에 대한 많은 근거를 다루고 있습니다. 이 가이드를 최대한 활용하려면 코드를 작성하는 것이 도움이 됩니다.

바로 들어가 보겠습니다, 여러분!

소스 코드 : 평소와 같이 다음에서 호스팅되는 소스 코드를 포크하고 수정할 수 있습니다. GitHub의.

참고 : Postman을 사용하여 데모에서 API를 테스트할 것입니다. 에서 다운로드 할 수 있습니다. 우편 배달부 다운로드 페이지. 또는 단순히 브라우저, 명령줄을 사용할 수 있습니다. curl 도구 또는 친숙한 다른 도구.

Nest.js란 무엇인가요?

Nest.js를 어려운 작업, 도구 및 상용구 코드를 추상화하는 동시에 최신 JavaScript 및 TypeScript를 사용하여 애플리케이션 개발을 위한 완전한 도구 키트를 추가하는 Node.js의 상위 집합으로 생각하세요.

Nest.js는 개발자와 팀이 Express.js 애플리케이션. Express(기본적으로 내부적으로 사용)를 Fastify로 바꿀 수도 있지만 그렇게 하면 애플리케이션에서 다른 Fastify 호환 라이브러리를 사용해야 할 수도 있습니다.

함수형 프로그래밍, 객체 지향 프로그래밍, 함수형 반응형 프로그래밍의 기능을 결합하고 52.4개가 넘는 별과 6.2개의 포크를 보유하고 있습니다. GitHub의 주간 다운로드 횟수는 최대 1,784,004건에 달하며, 진보적인 Node.js 프레임워크는 효율적이고 확장 가능한 엔터프라이즈급 서버 측 애플리케이션을 제작하는 데 널리 사용됩니다.

Nest.js의 특징

Nest.js가 인기 있는 Node.js 프레임워크로 성장한 이유는 다음과 같습니다.

  1. Nest.js는 개발자가 모놀리식 애플리케이션과 마이크로서비스를 모두 구축할 수 있도록 돕기 위해 만들어졌습니다.
  2. 강력하면서도 개발자 친화적으로 작업할 수 있습니다. 사용하기 쉽고, 배우기 쉽고, 적용하기 쉽습니다.
  3. 이는 기본적으로 TypeScript(JavaScript의 상위 집합)를 활용하고 개발자가 런타임 오류 없이 유지 관리 가능한 코드를 작성할 수 있는 공간을 제공합니다.
  4. 개발자의 생산성과 개발 용이성을 높이는 데 도움이 되는 명령줄 인터페이스를 보유하고 있습니다.
  5. Nest.js로 빌드하면 Nest에는 기본적으로 놀라운 프로젝트 폴더 구조가 함께 제공되므로 최소 실행 가능 제품을 부트스트래핑하든 애플리케이션 작업을 하든 개발 프로세스가 향상되고 시간이 절약됩니다.
  6. TypeORM, GraphQL, 로깅, 유효성 검사, Mongoose, WebSockets, 캐싱 등을 포함한 일반적인 개념과 기술의 통합을 돕는 다양한 Nest 관련 모듈을 지원합니다.
  7. Nest.js는 모든 프레임워크에 대한 최고의 문서를 보유하고 있다고 자랑할 수 있습니다. 문서는 철저하고 이해하기 쉬우며 문제에 대한 해결책이 필요할 때 쉽게 설명되므로 디버깅 시간을 절약하는 데 도움이 됩니다.
  8. Nest.js는 Jest와 통합되어 애플리케이션에서 단위 테스트를 간단하게 작성할 수 있습니다.
  9. 이는 소규모 및 대규모 엔터프라이즈 애플리케이션 모두를 위해 구축되었습니다.

Nest.js 프로젝트 만들기

로컬 컴퓨터에서 Nest.js를 시작하려면 먼저 새로운 Nest.js 프로젝트 폴더를 스캐폴드하고 프로젝트에 필요한 핵심 파일과 모듈로 폴더를 채우는 데 도움이 되는 Nest 명령줄 인터페이스(CLI)를 설치해야 합니다. Nest.js 애플리케이션.

Nest.js 명령줄 인터페이스를 설치하려면 다음 명령을 실행하세요.

$ npm i -g @nestjs/cli
// Or
$ yarn global add @nestjs/cli
// Or
$ pnpm add -g @nestjs/cli

로컬 컴퓨터에 Nest.js CLI를 전역적으로 성공적으로 설치한 후에는 다음을 실행할 수 있습니다. nest 명령줄에서 활용할 수 있는 다양한 명령을 확인하세요.

$ nest

결과 :

Usage: nest  [options]

Options:
  -v, --version                                   Output the current version.
  -h, --help                                      Output usage information.

Commands:
  new|n [options] [name]                          Generate Nest application.
  build [options] [app]                           Build Nest application.
  start [options] [app]                           Run Nest application.
  info|i                                          Display Nest project details.
  add [options]                          Adds support for an external library to your project.
  generate|g [options]  [name] [path]  Generate a Nest element.
    Schematics available on @nestjs/schematics collection:
      ┌───────────────┬─────────────┬──────────────────────────────────────────────┐
      │ name          │ alias       │ description                                  │
      │ application   │ application │ Generate a new application workspace         │
      │ class         │ cl          │ Generate a new class                         │
      │ configuration │ config      │ Generate a CLI configuration file            │
      │ controller    │ co          │ Generate a controller declaration            │
      │ decorator     │ d           │ Generate a custom decorator                  │
      │ filter        │ f           │ Generate a filter declaration                │
      │ gateway       │ ga          │ Generate a gateway declaration               │
      │ guard         │ gu          │ Generate a guard declaration                 │
      │ interceptor   │ itc         │ Generate an interceptor declaration          │
      │ interface     │ itf         │ Generate an interface                        │
      │ middleware    │ mi          │ Generate a middleware declaration            │
      │ module        │ mo          │ Generate a module declaration                │
      │ pipe          │ pi          │ Generate a pipe declaration                  │
      │ provider      │ pr          │ Generate a provider declaration              │
      │ resolver      │ r           │ Generate a GraphQL resolver declaration      │
      │ service       │ s           │ Generate a service declaration               │
      │ library       │ lib         │ Generate a new library within a monorepo     │
      │ sub-app       │ app         │ Generate a new application within a monorepo │
      │ resource      │ res         │ Generate a new CRUD resource                 │
      └───────────────┴─────────────┴──────────────────────────────────────────────┘

여기에서는 명령을 사용하는 방법을 보여 주며 이제 new|n [options] [name] 첫 번째 Nest.js 프로젝트를 생성하는 명령:

$ nest new getting-started-with-nestjs
// Or
$ nest n getting-started-with-nestjs

다음으로 어떤 패키지 관리자를 사용할 것인지 묻는 메시지가 표시됩니다.

? Which package manager would you ❤️ to use? (Use arrow keys)
  npm
  yarn
> pnpm

원하는 패키지 관리자를 자유롭게 선택하세요. pnpm. 이는 NPM보다 약 3배 더 효율적이고 빠르며, 빠른 캐시 시스템을 갖춘 PNPM도 Yarn보다 빠르기 때문입니다.

패키지 관리자를 선택한 후 설치 프로세스가 계속되면 Nest.js 앱이 생성됩니다.

이제 할 수 있습니다 cd 새로 생성된 프로젝트에 들어가서 원하는 편집기로 엽니다.

$ cd getting-started-with-nestjs

이제 프로젝트가 생성되었으므로 다음 명령 중 하나를 사용하여 실행할 수 있습니다.

$ npm run start
// Or
$ yarn start
// Or
$ pnpm run start

살펴보시면 package.json 파일의 스크립트 세그먼트에서 다음 값을 확인할 수 있습니다. pnpm run start is nest start:


    
"start": "nest start",

즉, 다음을 실행하여 Nest.js 앱을 실행할 수도 있습니다.

$ nest start

Nest.js 프로젝트 구조 살펴보기

Nest 앱의 구조를 자세히 살펴보겠습니다.

/package.json

XNUMXD덴탈의 package.json 파일은 Node.js의 핵심이며 더 나아가 Nest.js 프로젝트입니다. 이는 프로젝트에 대한 모든 메타데이터를 보유하고 애플리케이션 종속성을 설치하거나 프로젝트 스크립트를 실행하는 데 필요한 프로젝트의 다양한 기능 속성을 정의합니다.

우리는 이미 그 능력을 보았습니다. start 스크립트.

XNUMXD덴탈의 start:dev profile을 사용하면 애플리케이션을 중지하고 다시 시작할 필요 없이 애플리케이션의 변경 사항을 관찰하고 자동으로 다시 로드할 수 있으며 이는 개발용입니다. 그만큼 start:prod 스크립트는 Nest.js 앱을 테스트하기 위한 다른 스크립트와 함께 애플리케이션을 프로덕션에 배포할 때뿐만 아니라 프로덕션 준비가 되었는지 테스트하려는 경우에도 유용합니다.

@nestjs/platform-express Express를 Nest 애플리케이션의 기본 HTTP 서버로 정의합니다.

/tsconfig.json

XNUMXD덴탈의 tsconfig.json file은 Nest 앱을 컴파일하는 데 필요한 TypeScript 관련 옵션을 정의하는 JSON(JavaScript Object Notation)으로 작성된 파일입니다.

/nest-cli.json

여기에는 Nest 애플리케이션을 구축, 구성 또는 배포하는 데 필요한 메타데이터가 들어 있습니다.

/test

이 디렉터리에는 Nest 테스트를 실행하는 데 필요한 모든 파일이 들어 있습니다. Nest는 Jest 구성을 테스트하기 위해 Jest 프레임워크를 사용합니다. jest-e2e.json 파일.

/src

XNUMXD덴탈의 src 디렉토리는 Nest 프로젝트 핵심의 상위 폴더입니다. 그것은 보유 main.ts Nest 앱이 시작되는 파일입니다. 직업은 main.ts 파일을 로드하는 중입니다. AppModule 에서 수입되는 것 /src/app.module.ts.

이 가이드의 뒷부분에서는 모듈에 대해 알아봅니다. Nest.js 애플리케이션의 주요 구성 요소 중 하나입니다.

XNUMXD덴탈의 AppModule 모듈로 생성된 클래스입니다. @Module 데코레이터. 에서 app.module.ts 파일 AppService./app.serviceAppController./app.controller 수입되기도 합니다.

XNUMXD덴탈의 AppController 또한 다음을 사용하여 생성된 클래스입니다. @Controller 데코레이터, 반면 AppService 을 사용하여 생성된 클래스입니다. @Injectable 주석.

Nest의 멋진 점은 클래스에 메타데이터를 추가하는 데코레이터가 거의 없으며 메타데이터가 해당 클래스의 목적을 다음과 같이 정의한다는 것입니다.

  • @Controller()클래스를 컨트롤러로 변환합니다.
  • @Module() 클래스를 모듈로 변환합니다.
  • @Injectable() 클래스를 공급자로 변환합니다.

또한 src 디렉토리는 app.controller.spec.ts 컨트롤러용 테스트 파일입니다.

다음을 사용하여 앱을 실행할 수 있습니다. nest start.

앱이 시작되는 시간 http://localhost:3000 브라우저에서:

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

다음에 표시되는 콘텐츠를 변경할 수 있습니다. http://localhost:3000, 다음으로 이동하여 app.service.ts 인덱스 경로에 대한 공급자가 정의된 파일입니다.

Nest.js 앱의 구성 요소

Nest.js 애플리케이션에는 세 가지 주요 구성 요소가 있습니다.

  1. 모듈
  2. 컨트롤러
  3. 공급 업체

Nest 앱의 구성 요소에 대해 학습하면서 먼저 Nest 프로젝트를 삭제하여 정리하겠습니다. app.controller.spec.ts, ./app.service, app.module.ts./app.controller 파일; 방금 떠나는 중 main.ts, 처음부터 개발 수명주기를 에뮬레이션합니다.

이 시점에서 가져온 항목을 제거하면 AppModule 에서 파일 main.ts, '모듈'에 대한 인수가 제공되지 않았다는 메시지가 표시됩니다.

Nest 앱의 빌딩 블록을 시연하기 위해 객체에 대한 CRUD 작업을 처리하는 REST API를 구축하여 간단한 사용자 프로필 구현을 살펴보겠습니다.

모듈

. src 폴더 새로 만들기 app.module.ts 파일을 만든 다음 AppModule 우리가 내보내는 클래스입니다.

다음으로 가져오기 AppModule 수업하다 main.ts, 실행 nest start.

로 이동 http://localhost:3000 브라우저에서 404 오류가 발생합니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

이는 아직 Nest 앱의 기본 URL에 대한 경로를 정의하지 않았기 때문입니다.

뒤쪽에 app.module.ts우리는 AppModule 우리가 가지고 있는 클래스는 아직 Nest 모듈이 아닙니다. Nest 모듈로 만들기 위해 다음을 추가합니다. @Module() 다음에서 가져온 데코레이터 @nestjs/common그런 다음 빈 객체를 전달합니다.



import { Module } from '@nestjs/common';
@Module({})

export class AppModule {}

이제 Nest.js 모듈이 생겼습니다!

참고 : 모듈은 주석이 달린 클래스입니다. @Module() 데코레이터.

모든 Nest 애플리케이션에는 Nest 애플리케이션의 구조와 관계를 해결하기 위한 진입점 역할을 하는 루트 모듈이 있습니다.

애플리케이션의 구성 요소를 구성하려면 여러 모듈을 사용하는 것이 좋습니다.

XNUMXD덴탈의 @Module() 데코레이터를 사용하면 개발자가 Nest 앱의 클래스에 대한 메타데이터를 정의할 수 있습니다.

사용자 모듈, 주문 모듈, 채팅 모듈 등 여러 모듈이 있는 경우 app.module.ts Nest 앱의 다른 모든 모듈을 등록하는 데 사용해야 합니다.

경로 생성; 컨트롤러

Nest 애플리케이션에서 경로를 생성하려면 컨트롤러가 필요합니다. 컨트롤러의 목적은 Nest 애플리케이션에 대한 특정 요청을 수신하는 것입니다. 애플리케이션 내의 다양한 경로에 대한 요청 및 응답 주기를 제어합니다.

클라이언트에서 Nest 애플리케이션으로 HTTP 요청이 이루어지면 요청이 이루어지는 경로와 일치하는 경로가 요청을 처리하고 적절한 응답을 반환합니다.

Nest 앱에서 컨트롤러를 만들려면 @Controller() 데코레이터.

. src 디렉토리, 새 파일 생성 app.contoller.ts, 여기서 Nest 컨트롤러를 정의할 수 있습니다.

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

@Controller({})

export class AppController {}

그게 다야! 매우 훌륭한 컨트롤러가 있지만 새 경로를 생성하려면 먼저 생성된 컨트롤러에 대해 Nest 앱에 알려야 합니다.

이를 달성하려면 AppController app.module.ts에서 컨트롤러에 대한 정보를 정의합니다. @Module() 데코레이터 – 컨트롤러 배열로:



import { Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  controllers: [AppController],
})

export class AppModule {}

GET 요청 처리

그러면 우리는 간단하게 정의합니다. getUser() 경로( @Get() 지정된 경로에 대한 HTTP GET 요청을 처리하는 데 사용되는 데코레이터)를 기본 경로로 사용하려면 브라우저에서 동일한 경로에 액세스할 수 있습니다. https://localhost:3000:



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

@Controller({})

export class AppController {
  @Get()
  getUser() {
    return 'I am a great person';
  }
}

결과 :

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

흠, 여기서는 문자열만 반환하고 있는데 객체를 반환하고 싶다면 어떻게 해야 할까요? 문자열 대신 객체를 정의할 수 있습니다.



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

@Controller({})

export class AppController {
  @Get()
  getUser() {
    return { name: 'Uchechukwu Azubuko', country: 'Nigeria' };
  }
}

로 이동 http://localhost:3000 브라우저에 다음 개체가 표시됩니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

기본 경로에서 벗어나 다음과 유사한 경로를 만드는 것은 어떻습니까? http://localhost:3000/user 모든 사용자를 가져오려면?

몇 가지 방법으로 이러한 경로를 처리하는 컨트롤러를 만들 수 있습니다.

한 가지 방법은 다음을 사용하여 새로운 메서드를 정의하는 것입니다. @Get() 데코레이터/핸들러.

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

@Controller({})

export class AppController {
  @Get()
  getUser() {
    return { name: 'Uchechukwu Azubuko', country: 'Nigeria' };
  }
}

Nest.js는 다음을 포함하여 다양한 HTTP 메소드 모두에 데코레이터 또는 핸들러를 제공합니다. @Get(), @Post(), @Put(), @Delete(), @Patch(), @Options()@Head().

XNUMXD덴탈의 @All() 데코레이터는 다양한 메소드를 모두 처리하는 엔드포인트를 정의합니다.

POST 요청 처리

또한 다음을 사용하여 데이터베이스에 데이터를 저장하기 위한 POST 요청을 정의할 수도 있습니다. @Post() 데코레이터:

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

@Controller({})
export class AppController {
  @Post()
  store() {
    return 'Post request successful';
  }
}

그런 다음 Postman을 사용하여 POST 요청을 테스트하고 정의된 대로 문자열이 성공적으로 반환되는 것을 확인합니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

데이터를 반환하는 것 이상의 작업을 수행하려면 어떻게 해야 합니까? 아마도 데이터를 보내기 위해서일 것입니다.

이를 위해서는 다음과 같이 경로 메서드 내부에 데이터를 주입해야 합니다.

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

@Controller({})
export class AppController {
  @Post()
  store(@Req() req: Request) {
    return req.body;
  }
}

이제 Postman으로 POST 요청을 테스트하면 전송되는 데이터를 볼 수 있습니다. 이 경우에는 빈 객체일 뿐입니다.

모범 사례, 업계에서 인정하는 표준 및 포함된 치트 시트가 포함된 Git 학습에 대한 실습 가이드를 확인하십시오. 인터넷 검색 Git 명령을 중지하고 실제로 배움 이것!

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

경로 매개변수를 사용한 동적 라우팅

요청의 일부로 동적 데이터를 수락한다고 가정해 보겠습니다. 먼저 경로/URL의 동적 위치를 기록하기 위해 경로 경로에 토큰을 정의한 다음 @Param() 데코레이터의 경우 다음과 같이 경로 매개변수에 액세스할 수 있습니다.

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

@Controller({})
export class AppController {
  @Get('/:userId')
  getUser(@Param() userId: number) {
    return userId;
  }
}

XNUMXD덴탈의 userId 성공적으로 반환되었습니다:

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

비동기식 요청 처리

Nest.js는 다양한 접근 방식을 사용하여 약속을 반환하는 비동기 요청을 처리할 수 있습니다.

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

@Controller({})
export class AppController {
  @Get()
  async findAll(): Promise {
    return [];
  }
}

위의 접근 방식에서 비동기성은 다음을 사용하여 처리됩니다. async 예어. 또 다른 접근 방식은 RxJS 관찰 가능한 스트림을 반환하는 것입니다.

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

@Controller({})
export class AppController {
  @Get()
  findAll(): Observable {
    return of([]);
  }
}

여기에서 Nest.js는 내부적으로 소스를 구독하고 스트림이 완료되면 마지막으로 내보낸 값을 자동으로 가져옵니다.

Nest에서 리디렉션 처리

XNUMXD덴탈의 @Redirect() 데코레이터는 응답을 다른 URL로 리디렉션하는 데 사용됩니다. 그만큼 @Redirect() 데코레이터는 리디렉션할 URL과 리디렉션 시 상태 코드라는 두 가지 인수를 허용하며 둘 다 선택 사항입니다.

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

@Controller({})
export class AppController {
  @Get()
  @Redirect('https://www.ucheazubuko.com', 302)
  getSite() {
    return { url: 'https://stackabuse.com' };
  }
}

상태 코드 반환

Nest.js 서버에서 처리된 모든 요청에 ​​대한 상태 코드를 반환하려면 @HttpCode(…) 쉽게 통과됩니다.

Nest에서 GET 요청의 기본 상태 코드는 200, POST 요청은 201, 오류 요청은 304입니다.

서버 요청의 상태 코드는 아래와 같이 정의할 수 있습니다.

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

@Controller({})
export class AppController {
  @Post()
  @HttpCode(204)
  create() {
    return 'This action adds a new user to the app.';
  }
}

DELETE 요청 처리

POST 요청과 유사하게 삭제 요청은 다음과 같이 처리될 수 있습니다.

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

@Controller({})
export class AppController {
  @Delete('/:userId')
  delete(@Param() params: { userId: number }) {
    return params;
  }
}

UPDATE 요청 처리

서버의 특정 데이터를 업데이트하라는 요청은 다음을 사용하여 처리할 수 있습니다. @Patch() 데코레이터:

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

@Controller({})
export class AppController {
  @Patch('/:userId')
  update(@Req() req: Request) {
    return req.body;
  }
}

이제 우리는 강력한 서버에서 흔히 볼 수 있는 일반적인 컨트롤러를 정의하는 다양한 방법을 살펴보았으므로 컨트롤러는 간결하고 깔끔하며 사용 사례별로 정의되어야 한다는 점에 유의하는 것이 중요합니다. user 그런 다음 별도의 디렉터리를 생성하고 동일한 디렉터리를 처리하기 위해 전용으로 사용해야 합니다. AppController.

그런 다음 user.controller.ts, 우리는 그 안에 있는 모든 경로 핸들러에 접두사가 붙도록 구성할 수 있습니다. /user/ 아래와 같이 코드를 작성하여:



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

@Controller('/user')
export class UserController {
  @Get()
  getUser() {
    return 'I am from the user controller';
  }
}

다음으로 등록 UserController 컨트롤러의 배열에서 app.modules.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { UserController } from './controllers/user/user.controller';

@Module({
  controllers: [AppController, UserController],
})

export class AppModule {}

우리가 탐색 할 때 https:localhost:3000/user, 성공적으로 반환됩니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

프로젝트 폴더를 지금보다 더 깔끔하게 유지하기 위해 다음을 정의할 수 있습니다. user.module.ts 우리가 정의할 파일 UserController:

import { Module } from '@nestjs/common';
import { UserController } from './user.controller';

@Module({
  controllers: [UserController],
})

export class UserModule {}

그런 다음 가져오기 UserModule 으로 app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { UserModule } from './user/user.module';

@Module({
  controllers: [AppController],
  imports: [UserModule],
})

export class AppModule {}

이를 통해 이전과 동일한 효과를 얻을 수 있습니다.

참고 : Nest를 사용하면 모듈과 컨트롤러를 쉽게 (g)생성할 수 있습니다. nest g monest g co 명령. 다음과 같은 특정 모듈 user 모듈과 컨트롤러는 Nest CLI를 사용하여 다음 명령을 실행하여 빠르게 생성할 수도 있습니다. nest g mo user – 사용자 모듈을 생성하고 nest g co user – 사용자 컨트롤러를 생성합니다.

공급 업체

데이터베이스에서 데이터를 가져오는 모든 작업은 컨트롤러가 아닌 공급자가 처리하여 사용자 대상 코드와 잠재적으로 민감한 데이터와 상호 작용하는 코드 사이에 추상화 계층을 만들어야 합니다. 이러한 계층 사이에서 적절한 데이터베이스 처리를 보장하기 위해 유효성 검사를 설정할 수 있습니다. Nest CLI를 사용하면 서비스를 생성하여 공급자를 만들 수 있습니다.

$ nest g s user

이렇게하면 UserService 여기서 우리는 UserController그래서 그 UserController 요청과 응답만 처리합니다. ~ 안에 user.service.ts, 우리는 @Injectable() 데코레이터는 클래스를 정의하는 데 사용됩니다. Nest에서는 @Injectable() 데코레이터는 서비스, 저장소 또는 도우미 클래스를 공급자로 변환하는 것입니다.

공급자는 생성자를 통해 클래스에 주입됩니다. 예를 자세히 살펴보겠습니다.

이전에 user.controller.ts, 우리는 사용자 객체를 얻기 위한 비즈니스 로직을 정의했지만 이제는 UserService:



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

@Controller({})

export class AppController {
  @Injectable()
  get() {
    return { name: 'Uchechukwu Azubuko', country: 'Nigeria'; };
  }
}

다음으로 user.controller.ts 파일에서 생성자를 정의해 보겠습니다. UserController 수업. 이 생성자에서는 비공개를 제공합니다. userService, 이는 다음의 유형입니다. UserService 수업. 이 private을 사용하면 이전에 사용자를 가져오기 위해 정의한 비즈니스 논리를 활용할 수 있습니다.



import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';

@Controller('/user')
export class UserController {
  constructor(private userService: UserService) {}
  @Get()
  getUser() {
    return this.userService.get();
  }
}

그래서 UserController 클래스는 이제 다음에 따라 달라집니다. UserService 클래스라고 알려진 개념의 클래스
의존성 주입.

마찬가지로, 두 논리 모두 user.controller.tsuser.service.ts 그에 따라 파일이 업데이트됩니다.



import {
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Req,
} from '@nestjs/common';
import { Request } from 'express';
import { UserService } from './user.service';

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}
  @Get()
  getUsers() {
    return this.userService.get();
  }
  @Get('/:userId')
  getUser(@Param() param: { userId: number }) {
    return this.userService.getUser(param);
  }
  @Post()
  store(@Req() req: Request) {
    return this.userService.create(req);
  }
  @Patch('/:userId')
  update(@Req() req: Request, @Param() param: { userId: number }) {
    return this.userService.update(req, param);
  }
  @Delete()
  delete(@Param() param: { userId: number }) {
    return this.userService.delete(param);
  }
}


import { Injectable } from '@nestjs/common';
import { Request } from 'express';

@Injectable()
export class UserService {
  get() {
    return { name: 'Uchechukwu Azubuko', country: 'Nigeria' };
  }
  getUser(param: { userId: number }) {
    return param;
  }
  create(req: Request) {
    return req.body;
  }
  update(req: Request, param: { userId: number }) {
    return { body: req.body, param };
  }
  delete(param: { userId: number }) {
    return param;
  }
}

이제 Postman을 사용하여 엔드포인트가 제대로 작동하는지 확인해 보겠습니다.

Nest.js의 종속성 주입 이해하기

클래스나 모듈과 같은 애플리케이션의 더 작은 구성 요소를 구축할 때 클래스는 다른 클래스나 모듈의 기능에 따라 달라질 수 있습니다. 예를 들어 API 호출을 위해 다른 클래스에서 제공하는 HTTP 서비스를 탭해야 할 필요가 있습니다. 지속성 계층과 상호 작용하는 서비스 계층.

다음을 통해 컨트롤러 내에서 종속성을 제공할 수 있습니다. 의존성 주입.

종속성 주입은 높은 응집력을 제공하지만 느슨한 결합을 제공하는 방식으로 애플리케이션의 일부가 이를 필요로 하는 애플리케이션의 다른 부분에 전달되는 방식을 표현하는 프로그래밍 개념 및 패턴입니다.

Nest는 종속성 주입을 지원하며 Nest 애플리케이션에서 이를 사용하여 프로젝트의 모듈성을 향상시킬 수 있습니다.

실제적인 그림은 다음과 같이 묘사됩니다:

클래스 A가 클래스 B의 일부 기능을 사용한다고 가정합니다. 그러면 클래스 A가 클래스 B에 의존한다고 합니다. 따라서 클래스 A에서 클래스 B를 사용하려면 먼저 클래스 B의 인스턴스를 생성해야 합니다. 클래스 B 객체): const b = new B ().
클래스의 인스턴스를 생성하는 작업을 다른 클래스로 전송하고 제공되는 클래스(인젝터 구성 요소)의 종속성을 직접 사용하는 것을 종속성 주입이라고 합니다.

조언: 종속성 주입(DI)은 Spring Boot, Nest.js 및 Angular.js와 같은 프레임워크의 기본 개념 중 하나입니다. 이에 대해 자세히 알아보려면 다음을 확인하세요. 공식 Angular 문서.

일반적으로 클래스는 필요할 수도 있고 필요하지 않을 수도 있는 다양한 객체를 생성하는 데 사용되기보다는 해당 기능을 수행하는 데에만 집중해야 합니다.

의존성 주입의 이점.

  1. 단위 테스트에 도움이 됩니다.
  2. 종속성 주입을 사용하면 종속성 초기화가 주입기 구성 요소에 의해 수행되므로 상용구 코드가 줄어듭니다.
  3. 애플리케이션 확장 프로세스가 더 쉬워집니다.
  4. 종속성 주입은 느슨한 결합을 활성화하는 데 도움이 됩니다.

요청 페이로드 탐색

POST 및 PATCH와 같은 다양한 요청 핸들러에서 우리는 다음을 사용하여 서버에서 보낸 요청을 활용할 수 있었습니다. @Req() 데코레이터. 그러나 그 이상의 것이 있습니다.

전체 요청 개체를 검색하는 대신 필요한 요청 개체의 특정 부분을 활용할 수 있습니다.
따라서 Nest는 Fastify 객체의 Express에 액세스하기 위해 HTTP 경로 핸들러와 함께 사용할 수 있는 다양한 데코레이터를 제공합니다.

둥지 장식가 액세스되는 개체를 Fastify 또는 Express
`@Request(), @Req()` `요구`
`@Response(), @Res()` '다시'
`@다음()` '다음'
`@세션()` `요청 세션`
`@Param(param?: string)` `req.params` / `req.params[param]`
`@Body(매개변수?: 문자열)` `req.body` / `req.body[param]`
`@쿼리(매개변수?: 문자열)` `req.query` / `req.query[매개변수]`
`@Headers(param?: string)` `req.headers` / `req.headers[param]`
`@IP()` `req.ip`
`@HostParam()` `req.hosts`

전형적인 예는 @Req() 이전에 결과 본문에 액세스하기 위해 사용한 데코레이터는 다음과 같습니다. @Body() 드릴링 없이도 요청 본문에 직접 액세스할 수 있습니다.



@Post()
store(@Body() body: any) {
  return this.userService.create(body);
}

@Patch('/:userId')
update(@Body() body: any, @Param() param: { userId: number }) {
  return this.userService.update(body, param);
}


create(body: any) {
  return body;
}

update(body: any, param: { userId: number }) {
  return { body: body, param };
}

어떤 경우에는 요청 페이로드의 특정 속성만 검색하려고 할 수도 있습니다. 이 경우 DTO(데이터 전송 개체) 스키마를 정의해야 합니다. 데이터 전송 스키마는 검색되는 개체의 복사본을 정의하는 개체이지만 주로 저장하거나 검색할 개체와 지속성 계층 간에 데이터를 전송하는 데 사용됩니다. 일반적으로 이 프로세스는 공격에 더 취약하므로 DTO에는 민감한 데이터 포인트가 많이 포함되어 있지 않습니다. 이 특성을 사용하면 개체의 특정 필드만 검색할 수도 있습니다.

Nest에서는 컴파일 중에 클래스 값이 유지되므로 클래스를 사용하여 데이터 전송 객체를 정의하는 것이 좋습니다.

요청 본문에 토큰이 있고 이러한 데이터를 검색하거나 업데이트하고 싶지 않다고 가정하면 아래와 같이 DTO를 정의할 수 있습니다.



@Patch('/:userId')
update(
  @Body() updateUserDto: { name: string; email: string },
  @Param() param: { userId: number },
) {
  return this.userService.update(updateUserDto, param);
}


update(
  updateUserDto: { name: string; email: string },
  param: { userId: number },
) {
  return { body: updateUserDto, param };
}

그러나 우리는 다음에 대한 유형을 정의했음을 알 수 있습니다. updateUserDto 두 배; ~에 user.service.ts 으로 혹은 user.controller.ts, 그러나 코드 베이스 주위에서 반복되지 않도록 코드를 DRY(반복하지 마십시오)로 유지해야 합니다.

이를 위해 새 폴더에 /user/dto FBI 증오 범죄 보고서 /user 디렉토리, 파일을 생성해야 합니다 /update-user.dto.ts 와 더불어 .dto.ts 우리가 정의하고 내보내는 확장 UpdateUserDto 에서 사용할 클래스 user.service.tsuser.controller.ts 파일 :



export class UpdateUserDto {
  name: string;
  email: string;
}

...
import { UpdateUserDto } from './dto/update-user.dto';

@Patch('/:userId')
update(
  @Body() updateUserDto: UpdateUserDto,
  @Param() param: { userId: number },
) {
  return this.userService.update(updateUserDto, param);
}

...
import { UpdateUserDto } from './dto/update-user.dto';

update(updateUserDto: UpdateUserDto, param: { userId: number }) {
  return { body: updateUserDto, param };
}

파이프 및 검증

서버를 통해 요청이 이루어질 때 얻은 데이터의 유효성을 검사해야 한다고 가정해 보겠습니다.

Nest에서는 두 가지 종속성을 설치하는 파이프를 사용하여 애플리케이션에 들어오고 나가는 모든 데이터의 정확성을 테스트할 수 있습니다. class-validatorclass-transformer.

파이프는 다음과 같이 정의된 클래스입니다. @Injectable() 데코레이터(따라서 파이프는 공급자임) PipeTransform 상호 작용. 데이터를 원하는 형식으로 변환하고 데이터를 평가하여 데이터가 유효한 것으로 확인되면 변경되지 않은 상태로 전달되고, 그렇지 않으면 예외가 발생합니다. 파이프를 사용하려면 특정 파이프 클래스의 인스턴스를 적절한 컨텍스트에 바인딩해야 합니다.

XNUMXD덴탈의 class-validator 패키지를 사용하면 데코레이터와 데코레이터가 아닌 것을 확인할 수 있습니다. 유효성 검사기.js 내부적으로. 동안 class-transformer 패키지를 사용하면 객체를 클래스의 인스턴스로 변환하고, 클래스를 객체로 변환하고, 특정 기준에 따라 객체를 직렬화 또는 역직렬화할 수 있습니다.

Nest에서 제공하는 8개의 파이프는 다음과 같습니다.

  • ValidationPipe
  • ParseArrayPipe
  • ParseIntPipe
  • ParseUUIDPipe
  • ParseBoolPipe
  • DefaultValuePipe
  • ParseEnumPipe
  • ParseFloatPipe

이 가이드에서는 Nest의 유효성 검사를 시연하기 위해 내장된 ValidationPipe 이는 요청 페이로드에 대한 유효성 검사를 시행할 수 있게 하며 다음과 잘 결합됩니다. class-validator 패키지; 특정 규칙은 각 모듈의 데이터 전송 개체/로컬 클래스 선언에 간단한 주석을 사용하여 선언됩니다.

내장된 기능을 사용하려면 ValidationPipe 에서 수출되는 것 @nestjs/common, 우리가 설치하자 class-validatorclass-transformer 패키지 :

$ npm i --save class-validator class-transformer
# Or
$ yarn add class-validator class-transformer
# Or
$ pnpm install class-validator class-transformer

다음으로 이동합니다. main.ts 우리가 묶을 곳 ValidationPipe 앱의 모든 엔드포인트가 유효하지 않은 데이터 검색으로부터 보호되도록 애플리케이션의 루트 수준에서 다음을 수행합니다.



import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}

bootstrap();

다음으로, 각 모듈의 데이터 전송 객체 선언에서 각 개별 데이터에 대한 적절한 데이터 검사를 선언하여 몇 가지 유효성 검사 규칙을 추가합니다. 우리의 경우에는 다음에 대한 적절한 유효성 검사 규칙을 선언합니다. nameemail in UpdateUserDto:



import { IsEmail, IsString } from 'class-validator';

export class UpdateUserDto {
  @IsString()
  name: string;

  @IsEmail()
  email: string;
}

XNUMXD덴탈의 @IsString() 데코레이터는 주어진 데이터가 실제 문자열인지 확인하고 @IsEmail() 유효성 검사기는 주어진 데이터가 이메일인지 확인하고, 그렇지 않으면 false를 반환하고 예외를 발생시킵니다.

이제 우리가 PATCH 사용자 프로필을 요청하고 유효한 이메일 대신 숫자를 입력하세요. 예를 들어 예외가 발생합니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

이를 통해 Nest 앱에서 매우 훌륭한 유효성 검사를 받았습니다.

확인하는 동안 ValidationPipe, 메소드 핸들러가 수신하지 않기를 원하는 속성을 필터링하는 것도 가능합니다. 예를 들어 핸들러가 nameemail 속성이지만 요청에는 country 속성을 제거할 수 있습니다. country 설정을 통해 결과 객체의 속성 whitelisttrue 인스턴스화할 때 ValidationPipe:



import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
    }),
  );
  await app.listen(3000);
}

bootstrap();

메소드 매개변수 수준에서 파이프 바인딩

파이프는 다음에서도 정의할 수 있습니다. params, 또한. 이를 위해 메서드의 매개변수 수준에서 파이프를 바인딩합니다.

이전에는 userId 숫자가 되려면 우리가 userId 문자열로는 다음과 관계없이 성공한 것으로 나타납니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

가치를 보장하기 위해 userId 항상 숫자여야 하며, 바인딩을 선언합니다. getUser() 동일한 것을 보장하는 유효성 검사가 포함된 메소드 핸들러:


...
import { ParseIntPipe } from '@nestjs/common';

@Get('/:userId')
getUser(@Param('userId', ParseIntPipe) userId: number) {
  return this.userService.getUser(userId);
}


getUser(userId: number) {
  return { userId };
}

XNUMXD덴탈의 ParseIntPipe 내장 ParseInt 파이프를 정의하고 실행 대상 데이터가 정수여야 함을 보장합니다.

이제 우리가 만들 때 GET 잘못된 요청 userId 문자열 "ab"의 경우 유효성 검사가 실패하고 예외가 발생합니다. 400 상태 코드:

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

그러나 숫자 값을 사용하면 유효성 검사가 성공적으로 통과됩니다.

Nest.js 가이드 - Nest 및 Node PlatoBlockchain 데이터 인텔리전스를 사용하여 REST API 구축. 수직 검색. 일체 포함.

적절한 유효성 검사를 보장하기 위해 그에 따라 다른 메소드 핸들러를 업데이트할 수도 있습니다.



import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  Req,
} from '@nestjs/common';
import { Request } from 'express';
import { UserService } from './user.service';

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}
  @Get()
  getUsers() {
    return this.userService.get();
  }
  @Get('/:userId')
  getUser(@Param('userId', ParseIntPipe) userId: number) {
    return this.userService.getUser(userId);
  }
  @Post()
  store(@Req() req: Request) {
    return this.userService.create(req);
  }
  @Patch('/:userId')
  update(
    @Body() updateUserDto: { name: string; email: string },
    @Param('userId', ParseIntPipe) userId: number,
  ) {
    return this.userService.update(updateUserDto, userId);
  }
  @Delete()
  delete(@Param('userId', ParseIntPipe) userId: number) {
    return this.userService.delete(userId);
  }
}


import { Injectable } from '@nestjs/common';
import { Request } from 'express';
import { UpdateUserDto } from './dto/user-update.dto';

@Injectable()
export class UserService {
  get() {
    return { name: 'Uchechukwu Azubuko', country: 'Nigeria' };
  }
  getUser(userId: number) {
    return { userId };
  }
  create(req: Request) {
    return req.body;
  }
  update(updateUserDto: UpdateUserDto, userId: number) {
    return { body: updateUserDto, userId };
  }
  delete(userId: number) {
    return { userId };
  }
}

이제 우리는 언제든지 외부 소스에서 애플리케이션으로 들어오는 데이터의 유효성을 검사하는 모범 사례 기술을 확보했습니다.

결론

이 가이드에서는 Node.js 블록의 최신 소식에 대해 배울 수 있었습니다. Nest.js 및 이를 사용하여 애플리케이션을 구축하려는 경우 시작하는 데 필요한 모든 것입니다. Nest의 정의, 기능, Nest 프로젝트 생성 방법, Nest 앱으로 수신되는 데이터를 처리하는 방법, 수신 데이터의 유효성을 검사하는 방법을 배웠습니다. 전체적으로 Nest 애플리케이션의 구성 요소와 각 구성 요소가 Nest.js 애플리케이션에 제공하는 가치에 대해 배웠습니다.

이 시점부터 Nest를 사용하여 엔터프라이즈급 애플리케이션을 구축하는 것과 관련하여 배워야 할 것이 여전히 많지만 앞으로 있을 모든 작업을 시작하고 실행할 수 있는 기본 개념을 성공적으로 다룰 수 있었습니다.

Nest 및 MySQL을 사용하여 Restful API를 구축하는 방법을 배우는 향후 새로운 가이드를 기대해 주세요.

읽어 주셔서 감사합니다!

추가 자료

Nest.js 문서
각도 문서

타임 스탬프 :

더보기 스택카부스