반응형

다음은 이 글의 동영상 강의입니다.

https://youtu.be/v66oRI3peh8

아래는 컨트롤러 실습 강의 영상입니다.

https://youtu.be/BJbL6zT16DM

 

* 이글은 NestJS 홈페이지를 참조하여 작성하였습니다.

https://docs.nestjs.kr/controllers

 

네스트JS 한국어 매뉴얼 사이트

네스트JS 한국, 네스트JS Korea 한국어 매뉴얼

docs.nestjs.kr

 

Controller의 역할

NestJS의 Controller는 Client의 request(요청)를 받아 처리한 후 response(응답)하는 역할을 합니다.

Client의 요청이 들어왔을 때 요청에 따라 처리할 Controller로 분기 처리하는 것을 Routing이라고 합니다.

 

@Controller()

Controller는 @Controller() 데코레이터를 사용합니다.

마지막에 사용된 () 안에는 다음과 같이 요청 라우팅 path를 지정할 수 있습니다.

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

@Controller('cats')
export class CatsController {}

이때 정의된 cats는 하위 메소드들의 접두어 역할을 하므로 반복하여 작성할 필요가 없습니다.

 

라우팅 path가 없을 경우에는 root path('/')로 사용됩니다.

사용 예는 다음과 같습니다.

  • http://localhost:3000/   =>  @Controller()
  • http://localhost:3000/cats   =>  @Controller('cats')

Controller에서는 다음과 같이 HTTP Request Method 데코레이터를 사용할 수 있습니다.

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

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

위의 @Get() 데코레이터는 Controller의 라우팅 패스를 상속 받기 때문에 Client에서는 다음과 같이 요청할 수 있습니다.

  • http://localhost:3000/cats

@Get() 데코레이터도 @Controller와 마찬가지로 routing path를 지정할 수 있습니다.

  • @Get('profile') 

이 경우 사용자의 요청 URL은 다음과 같습니다.

  • http://localhost:/3000/cats/profile

@Get() 데코레이터 아래 선언된 Method의 이름은 어떤 의미도 부여하지 않습니다.
다만, 코드를 해석하기 쉬운 형태로 작성해 주시면 됩니다.

 

Method 옆에 선언된 type은 response 형식입니다.

@Get()
findAll(): string

 

Request 객체

NestJS는 Express를 사용하고 있으므로 인해 Request 객체를 사용할 수 있습니다.

핸들러 parameter에 @Req() 데코레이터를 사용하면 됩니다.

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

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

 

Route parameters

동적 라우팅을 위해서는 매개변수를 ':'과 함께 사용할 수 있습니다.

다음은 동적 매개변수를 사용한 예입니다.

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

만약 id가 1일 경우 호출 url은 다음과 같습니다.

  • http://localhost:3000/cats/1

매개 변수는 @Param() 데코레이터로 받아서 처리하면 됩니다.

위에서는 params.id로 라우팅 매개변수 값을 추출할 수 있습니다.

다음과 같은 방법으로도 처리할 수 있습니다.

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

 

비동기 처리

비동기 함수는 아래 예제와 같이 Promise를 반환해야 합니다.

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

 

Post의 Body DTO

Post 라우트 핸들러에서는 @Body() 데코레이터를 사용할 수 있습니다.

이때 DTO 스키마 클래스를 생성해서 데이터를 처리할 수 있습니다.

다음은 DTO를 사용한 예제입니다.

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

 해당 DTO를 Controller에서 사용하는 방법은 다음과 같습니다.

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

 

일반적인 API의 구조를 모두 포함한 예제는 다음과 같습니다.

  • findAll : 전체 데이터 목록 조회
  • findOne : 데이터 상세 조회
  • create : 데이터 생성
  • update : 데이터 수정
  • remove : 데이터 삭제
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`;
  }
}

이상으로 nestjs의 controller에 대해 알아보았습니다.

반응형
반응형

다음은 이글의 동영상 강의 입니다.

https://youtu.be/mz03kWu0CvU

 

NestJS는 소스코드를 자동으로 생성해주는 Generator가 있습니다.

이 개념은 Angular의 Generator와 똑같은 기능을 수행합니다.

자동생성은 Module, Controller, Service등을 생성할 수 있습니다.

 

모듈 자동 생성하기

nest g module 모듈명

다음은 users 모듈을 generator로 생성한 것입니다.

generate module

module이 생성이 완료되면 다음과 같이 폴더와 파일이 생성된걸 보실 수 있습니다.

그리고, app.module.ts에 해당 모듈이 자동으로 import 됩니다.

이렇게 되면 UsersModule을 사용할 수 있게 됩니다.

 

Controller 자동 생성하기

다음 명령으로 Controller를 생성합니다.

nest g controller 컨트롤러명

명령이 완료되면 users.controller.ts가 생성되고, users.module.ts가 업데이트 됩니다.

users.module.ts에는 UsersController가 자동으로 추가 되었습니다.

users.controller.ts에는 'users'라는 라우팅 패스가 자동으로 추가되었습니다.

 

서비스 생성하기

다음 명령으로 service를 생성할 수 있습니다.

nest g service 서비스명

명령이 완료되면 users.service.ts 파일이 생성되고, user.module.ts가 업데이트 됩니다.

users.module.ts에는 providers에 UserService가 자동으로 추가됩니다.

생성된 users.service.ts는 다음과 같습니다.

Service는 @Injectable() 데코레이터를 사용합니다.

이는 스프링의 DI(Dependency Injection)이라는 개념을 사용하는 것입니다.

즉, Service를 사용할 곳에 선언해주면 필요한 시점에 자동으로 객체를 생성해주는 역할을 합니다.

이때 객체 생성시 사용하던 new를 사용할 필요가 없습니다.

 

이상으로 NestJS에서 Module, Controller, Service를 자동생성하는 법을 알아보았습니다.

반응형
반응형

이 글은 동영상 강의로 제공됩니다.

https://youtu.be/qmthF-dq3Ak

 

NestJS의 Module 개념

  • NestJS는 여러 모듈들의 집합입니다.
  • NestJS는 하나 이상의 모듈이 반드시 있어야 합니다.
  • 기본 모듈은 AppModule입니다.
  • 기능별로 모듈을 생성하여 개발할 수 있습니다.
  • 생성된 각 모듈을 Root Module에 imports 시켜주어야 합니다.(하위모듈의 하위모듈...)
  • CLI로 모듈을 생성하면 자동으로 Root Module에 import가 됩니다.
  • export를 통해 외부에서 module을 사용할 수 있습니다.

 

NestJS CLI로 생성된 소스를 자세히 살펴보겠습니다.

main.ts

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
  • main.ts는 Application의 진입점(Entry Point)입니다.
  • main.ts에서는 NestFactory를 사용하여 Application 인스턴스를 생성합니다.
  • 생성시에는 AppModule을 사용하도록 지정을 했습니다.

 

app.module.ts

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

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  • AppModule은 main.ts에서 지정한 root module입니다.
  • NestJS는 모듈 단위로 개발을 진행합니다.
  • module은 @Module 데코레이터를 사용하여 선언합니다.
  • imports는 다른 module을 가져올때 사용합니다.
  • controllers는 이 모듈에서 사용하는 컨트롤러의 세트입니다.
  • providers는 NestJS의 injector에 의해 인스턴스화 되는 class를 지정합니다.
  • export를 통해 모듈을 다른 곳에서 사용할 수 있습니다.

 

app.controller.ts

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}
  • controller는 client의 요청에 대한 라우팅을 처리합니다.
  • provider인 AppService에게 비즈니스 처리 요청을 보냅니다.
  • 서비스에서 받은 결과를 client에 응답으로 보냅니다.

app.service.ts

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

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}
  • controller의 요청을 받은 서비스는 비즈니스 로직을 처리한 후 controller에게 return합니다.

 

이상으로 NestJS의 구조에 대해 살펴보았습니다.

반응형
반응형

이 글의 동영상 강의입니다.

https://youtu.be/mcq-cqnFJD0

 

* 이 글은 MDN Javascript 안내서를 참조하여 작성하였습니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Introduction

 

Introduction - JavaScript | MDN

이 장은 JavaScript를 소개하고 그 일부 기초 개념을 다룹니다.

developer.mozilla.org

 

Javascript 실행 방법

Javascript 코드를 만들고 실행하는 방법은 다음과 같습니다.

  • test.js 파일을 만들고 test.html에서 test.js를 선언해서 사용할 수 있습니다.
<script src="./test.js"></script>
  • 크롬 브라우저 개발자 도구에서 콘솔에 javascript 코드를 입력하여 실행 할 수 있습니다.
    크롬 개발자 도구는 크롬 실행 후 F12 키를 눌러 실행 시킬 수 있습니다.

  • nodejs를 설치한 후 node 명령을 통해 실행할 수 있습니다.
    아래는 nodejs로 test.js를 실행하는 명령입니다.
node test

여기서는 주로 3번째 방법인 nodejs를 설치하여 테스트 하도록 하겠습니다.

 

문법

  • 대소문자를 구분합니다.
var name = "Spider Man";
var Name = "Iron Man";

console.log(name);
console.log(Name):
  • 크롬 브라우저의 개발자도구에서 실행한 결과는 다음과 같습니다.
    크롬 개발자도구는 브라우저 실행 후 F12를 누르면 나타납니다.

  • 주석은 다음과 같이 사용합니다.
// 한 줄 주석

/* 이건 더 긴,
 * 여러 줄 주석입니다.
 */

/* 그러나, /* 중첩된 주석은 쓸 수 없습니다 */ SyntaxError */
  • 명령문(Statement)는 세미콜론( ; )으로 구분합니다.
    한줄로 명령문이 끝날 경우에는 세미콜론을 사용하지 않아도 됩니다.
    하지만 프로그램의 가독성을 위해 저는 사용하는 것을 권합니다.
var name = "Spider Man";

 

선언

  • Javascript는 3가지 선언 방법이 있습니다.
    • var : 변수를 선언하고 동시에 값을 초기화 함.
    • let : 블록 범위 지역변수를 선언하고, 동시에 값을 초기화 함.
    • const : 블록 범위 읽기 전용 상수를 선언함. 
  • var는 scope과 hoisting 문제가 있습니다. 이로 인해 ES6 이후부터 나온 let과 const의 사용을 권합니다. 
  • 아래는 scope 문제의 예입니다.
var name = "Spider Man";
if (name) {
	var name = "Iron Man";
	console.log("I am " + name);
}
console.log("I am " + name);

실행 결과

  • if문 block에서 변경한 name의 값이 block 외부에도 영향을 미치고 있습니다.
  • 다음과 같이 let과 const를 사용하면 block scope을 갖게 됩니다.
let name = "Spider Man";
if (name) {
	let name = "Iron Man";
	console.log("I am " + name);
}
console.log("I am " + name);

실행결과

  • 아래는 hoisting 문제의 예입니다.
console.log(name);
var name = "Iron Man";
console.log(name);

실행 결과

  • name을 선언하지 않았지만 오류가 나지 않고 undefined라는 값을 출력했습니다.
  • 아래와 같이 let과 const를 사용하면 에러가 발생하게 됩니다.
console.log(name);
let name = "Iron Man";
console.log(name);

실행 결과

변수

  • 변수는 var와 let을 이용해 선언합니다.
  • 초기값이 없을 경우 undefined 값을 갖습니다.
var a;
console.log("a 값은 " + a); // "a 값은 undefined"로 로그가 남음.

let x;
console.log('x 값은 ' + x); // x 값은 undefined​
  • undefined를 갖는 변수는 if 문에서 false가 리턴됩니다.
var name;
if (name) {
	console.log("true");
}else {
   console.log("false");
}

 

상수

  • 상수는 const를 사용하여 선언합니다.
  • 상수는 초기에 설정된 값외에 다른 값으로 바꿀 수 없습니다.
  • 상수는 재선언할 수 없습니다.

 

데이터형

Javascript는 7가지 데이터 형을 정의합니다.

  • Boolean : true or false
  • null : 값이 없음
  • undefined : 값이 정의되지 않음
  • Number : 정수 또는 실수형 숫자. 예:5 or 3.14159
  • String : 문자열
  • Symbol : 고유하고 불변인 데이터 형
  • Object : 객체형

 

배열

Javascript에서 배열은 다음과 같이 []를 사용하여 선언합니다.

var coffees = ["French Roast", "Colombian", "Kona"];

 

Block

  • Block 문은 코드의 묶음을 나타내고 중괄호 "{ }"로 표시합니다.
{
  statement_1;
  statement_2;
  .
  .
  .
  statement_n;
}
  • Block 문은 일반적으로 제어문(if, for, while)과 함께 사용합니ㅏㄷ.
while (x < 10) {
  x++;
}

 

조건문

  • 조건문은 참인 경우에 실행하는 명령의 집합입니다.
  • javascript에서 조건문은 if...else와 switch 문이 있습니다.
if (condition) {
  statement_1;
} else {
  statement_2;
}
switch (expression) {
  case label_1:
    statements_1
    [break;]
  case label_2:
    statements_2
    [break;]
    ...
  default:
    statements_def
    [break;]
}

 

예외처리

  • javascript의 예외처리는 throw와 try...catch...finally문을 사용합니다.
throw "Error2";   // String type
throw 42;         // Number type
throw true;       // Boolean type
throw {toString: function() { return "I'm an object!"; } };
try {
  writeMyFile(theData); //This may throw a error
} catch(e) {
  handleError(e); // If we got a error we handle it
} finally {
  closeMyFile(); // always close the resource
}

 

javascript 기초적인 문법은 반드시 알고 있어야 하므로 모르실때마다 꼭 확인하는 습관을 들이시기 바랍니다.

반응형

'자바스크립트' 카테고리의 다른 글

JSON 기초 (feat. Live Server)  (0) 2021.10.16
반응형

 

이 글의 동영상 강의입니다.

https://youtu.be/lwJLrv6zj04

 

 

* Nestjs 개발을 위해서는 Nodejs가 설치되어 있어야 합니다.

* Editor는 Visual Studio Code(VSCode)를 사용했습니다.

 

NestJS 프로젝트를 만들기 위해서는 Nestjs CLI(Command Line Interface)를 설치해야 합니다.

  • 아래와 같이 Nestjs cli를 설치합니다.
npm i -g @nestjs/cli
  • 설치가 완료되면 아래와 같이 CLI를 이용해 프로젝트를 만들 수 있습니다.
nest new project-name

 

  • 생성된 프로젝트의 구조는 다음과 같습니다.
    • dist : typescript 코드를 컴파일해서 빌드한 .js 파일이 저장되는 폴더
    • node_moduels : package.json에 정의된 패키지 모듈이 설치되는 폴더
    • src : typescript 코드가 저장되는 사용자 소스 폴더
    • test : test 소스가 저장되는 폴더

nest project 구조

  • 자동생성된 프로젝트 소스 폴더의 구조는 다음과 같습니다.
    • app.controller.spec.ts : test용 소스 - controller를 테스트합니다.
    • app.controller.ts : controller 소스 - client의 request을 처리하고, response를 보냅니다. 
    • app.module.ts : module 소스 - 모듈을 정의합니다.(controller와 service 정의)
    • app.service.ts : service 소스 - controller가 요청한 비즈니스 로직을 처리합니다.
    • main.ts : 프로젝트 시작점(Entry Point)

src 폴더

  • main.ts
    • 애플리케이션 Entry Point 즉, 시작 소스입니다.
    • 서버를 스타트하고 포트 설정, CORS 등을 정의합니다.

  • package.json
    • 프로젝트의 설정 파일입니다.
    • 사용하는 모듈, 서버 실행 및 빌드등의 스크립트를 정의합니다.

 

프로젝트 실행

  • VSCode 상단메뉴에서 터미널-새터미널을 클릭합니다.
  • package.json에 정의된 실행 스크립트를 실행합니다.
npm start
  • 브라우저에서 다음 URL을 입력합니다.
http://localhost:3000
  • 브라우저에 다음과 같이 내용이 출력됩니다.

 

반응형
반응형

nestjs homepage

* 본 문서는 nestjs 홈페이지(https://docs.nestjs.com/)를 참조하였습니다.

* nestjs 한글 홈페이지 주소 : https://docs.nestjs.kr/

 

네스트JS 한국어 매뉴얼 사이트

네스트JS 한국, 네스트JS Korea 한국어 매뉴얼

docs.nestjs.kr

 

이 글의 동영상 강의입니다.

https://youtu.be/QniEcuwvLSU

 

Nest(NestJS)의 특징

  • Nest는 nodejs 서버 애플리케이션을 구축하기 위한 프레임워크입니다.
  • Nest는 서버 애플리케이션 개발시 필요한 많은 부분들을 기본적으로 제공하고 있습니다.
  • Nest는 Express 기반으로 만들어졌습니다.
  • Nest는Typescript를 사용합니다. javascript도 코딩이 가능합니다.
  • Nest는 다음 요소를 포함합니다.
    • OOP - 객체지향 프로그래밍
    • FP - Functional 프로그래밍
    • FRP - Functional React 프로그래밍
  • Nest는 외부 모듈을 자유롭게 이용할 수 있습니다.
  • Nest는 unit 테스트와 e2e 테스트를 할 수 있는 툴을 제공합니다.

Nest의 탄생배경

  • 최근 Nodejs로 인해 javascript를 이용한 풀스택(클라이언트+서버) 개발이 활발해졌습니다.
  • javascript라는 한가지 언어로 개발을 하기 때문에 생산성을 향상시키고 빠른 개발이 가능해졌습니다.
  • 그러나 Node.js의 높은 자유도로 인해 Architecture 구성이 어렵고 효과적이지 못했습니다.
  • 이를 해결하기 위해 Angular의 아키텍처 사상을 기반으로 Nest가 만들어졌습니다.

 

Nest를 사용하면 좋은 점

  • Nest는 Java의 Spring과 같이 규칙을 제공합니다. 
    이로 인해 개발자들이 아키텍처의 구성에 대해 고민해야 할 부분이 많이 줄어듭니다.
  • 기본적으로 제공하는 라우팅, 보안등의 기능이 많이 탑재되어 있어 편리합니다.
  • 외부모듈을 통한 확장이 얼마든지 가능합니다.
  • Java+Spring 사용자라면 아키텍처 구조가 비슷해서 쉽게 배울 수 있습니다.
  • Angular 사용자라면 기본적인 사용법이 동일하므로 쉽게 배울 수 있습니다.

반응형
반응형

이 글의 동영상 강의 입니다.

https://youtu.be/wb4qGjfocwI

 

Express에서 라우팅을 별도의 파일로 분리할 수 있습니다.

 

한개의 파일로 분리하는 경우

  • 다음과 같이 router.js 파일을 만듭니다.
const express = require('express');
var router = express.Router();

router.get('/', function (req, res) {
  res.send('Express Server!');
});

module.exports = router;
  • index.js 파일에서 router.js를 사용하도록 코드를 추가합니다.
const express = require('express');
const app = express();
 
app.listen(3000);

app.use(require('./router'));

 

여러개의 파일로 분리하는 경우

  • user-router.js 파일을 만들고 다음 코드를 추가합니다.
const express = require('express');
var router = express.Router();

router.get('/', function (req, res) {
  res.send('This is user-router!');
});

module.exports = router;
  • board-router.js 파일을 만들고 다음 코드를 추가합니다.
const express = require('express');
var router = express.Router();

router.get('/', function (req, res) {
  res.send('This is board-router!');
});

module.exports = router;
  • index.js를 다음과 같이 수정합니다.
const express = require('express');
const app = express();
 
app.listen(3000);

app.use('/', require('./router'));
app.use('/user', require('./user-router'));
app.use('/board', require('./board-router'));

 

반응형
반응형

아래는 이 글의 동영상 강의입니다.

https://youtu.be/ceNqxXQMuKw

 

* 본 문서는 아래 사이트를 참고하여 작성하였습니다.
https://expressjs.com/ko/guide/using-middleware.html

 

Express 미들웨어 사용

미들웨어 사용 Express는 자체적인 최소한의 기능을 갖춘 라우팅 및 미들웨어 웹 프레임워크이며, Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다. 미들웨어 함수는 요청 오

expressjs.com

 

Express는 client의 요청을 받아 처리할때 미들웨어라는 개념을 사용합니다.

Express 애플리케이션은 기본적으로 일련의 미들웨어 함수 호출입니다.

 

Express에는 다음과 같은 유형의 미들웨어가 있습니다.

  • 애플리케이션 레벨 미들웨어
  • 라우터 레벨 미들웨어
  • 오류 처리 미들웨어
  • 기본 제공 미들웨어
  • 써드파티 미들웨어

 

애플리케이션 레벨 미들웨어

  • 애플리케이션 미들웨어는 다음과 같이 사용할 수 있습니다.
  • app.use(미들웨어);
  • app.use(미들웨어1, 미들웨어2...);
  • app.use에서 선언된 function이 미들웨어 입니다.
const express = require('express');
const app = express();
app.listen(3000);

app.use(function(req, res){
  res.send('Express Server!!!');
});
  • 한개의 요청을 여러개의 미들웨어가 처리할 수 있습니다.
    • 요청 경로(path)가 포함되지 않은 요청은 항상 실행됩니다.
    • function에서 next 인자를 처리하면 하위 스택을 처리하게 됩니다.
app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});
  • client의 요청 경로(path)가 포함된 경우는 다음과 같이 처리합니다.
    • app.use(path, 미들웨어함수);
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});
  • 다음은 라우트를 사용하는 방법입니다.
    라우트는 client의 요청을 http method별로 처리할 수 있습니다.
    • app.메소드(path, 미들웨어);
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});
  • next를 사용해서 미들웨어를 여러개 실행할 수도 있습니다.
app.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});
  • 라우트 핸들러는 하나의 경로에 여러개의 라우트를 정의할 수 있습니다. 하지만 동일한 메소드를 2개 이상 만들고 앞에서 response를 처리하면 다음 메소드는 실행되지 않습니다.
app.get('/user/:id', function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});

// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
  res.end(req.params.id);
});

 

라우터레벨 미들웨어

  • express.Router()를 사용하면 라우터 레벨의 미들웨어를 사용할 수 있습니다.
var app = express();
var router = express.Router();
  • 위 선언으로 라우터레벨 미들웨어를 다음과 같이 사용할 수 있습니다.
    라우터에서도 use와 method를 사용합니다.
// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// a middleware sub-stack that handles GET requests to the /user/:id path
router.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next router
  if (req.params.id == 0) next('route');
  // otherwise pass control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

// mount the router on the app
app.use('/', router);

 

오류 처리 미들웨어

  • 오류 처리 미들웨어는 function의 parameter 첫번째 인자로 error를 받아 처리합니다.
app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

 

기본 제공 미들웨어

  • express에서 기본적으로 제공하는 미들웨어가 있습니다.
  • 다음은 기본제공 미들웨어 중 정적 모듈을 처리하는 static 미들웨어의 예제입니다.
app.use(express.static(__dirname+'/public'))
  • static으로 html 처리
    • http://localhost:3000/index.html 로 요청이 올경우 /public/index.html을 찾아 응답하게 됩니다.
  • static으로 이미지 처리
    • http://localhost:3000/logo.png 로 요청이 올경우 /public/logo.png를 찾아 응답하게 됩니다.
  • index.html 처리하기
    • http://localhost:3000 을 응답하는 코드는 다음과 같습니다.
app.get('/', function(req, res) {
  res.sendFile(__dirname+'/public/index.html')
});

 

써드 파티 미들웨어

  • express에서는 다양한 써드파티 미들웨어를 사용할 수 있습니다.
  • 필요한 기능에 따라 npm install을 사용하여 모듈을 설치하여 사용합니다.
  • 아래는 쿠키 구문 분석 미들웨어인 cookie-parser의 사용 방법 입니다.
  • 우선 cookie-parser 설치합니다.
npm install cookie-parser
  • 사용법은 다음과 같습니다.
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');

// load the cookie-parsing middleware
app.use(cookieParser());
  • 써드파티 미들웨어는 다음 링크에서 확인할 수 있습니다.

https://expressjs.com/ko/resources/middleware.html

 

Express 미들웨어

Express 미들웨어 목록에 적힌 Express 미들웨어 모듈들은 Expressjs 팀이 유지보수합니다. 미들웨어 모듈 설명 내장 함수 (Express 3) body-parser HTTP 요청 body를 파싱합니다. body, co-body, 그리고 raw-body도 참

expressjs.com

 

이상으로 express의 미들웨어에 대해 알아보았습니다.

반응형
반응형

NodeJS의 내부모듈인 http module을 사용해서 서버를 만들때 복잡하고 불편한 점들이 있습니다.

이를 개선한 NodeJS의 확장모듈인 express를 사용하는 방법을 알아봅니다.

 

다음은 이 글의 동영상 강의입니다.

https://youtu.be/Ej-N6c9JCbY

 

Express의 특징

  • Express는 모바일 및 웹용 애플리케이션 제작을 위한 일련의 기능을 제공하는 프레임워크입니다.
  • Express는 수많은 HTTP 유틸리티 메소드와 미들웨어를 통해 쉽고 빠르게 강력한 API를 제작할 수 있습니다.
  • Express는 빠른 성능을 제공합니다.
  • 많은 NodeJS 프레임워크들이 Express를 기반으로 하고 있습니다.

참조 : https://expressjs.com/ko

 

Express - Node.js 웹 애플리케이션 프레임워크

Node.js를 위한 빠르고 개방적인 간결한 웹 프레임워크 $ npm install express --save

expressjs.com

 

 

프로젝트 만들기

  • 프로젝트 폴더를 생성한 후 visual studio code를 실행합니다.
  • vscode의 메뉴에서 파일-폴더열기를 선택한 후 프로젝트폴더를 선택합니다.
  • 메뉴 터미널-새터미널을 선택한 후 다음을 입력하여 Nodejs프로젝트를 생성합니다.
npm init -y

 

express 설치

  • 우선 express 설치를 위해 npmjs.com에서 express를 검색합니다.
    리스트 중 제일 상단의 express (작성자:dougwilson)를 선택합니다.

npmjs.com

  • express의 설치 방법 사용예제 등을 확인합니다.

 

  • visual studio code의 터미널에서 다음 코드를 이용하여 expres를 설치합니다.
npm i express

 

프로그램 개발

  • vscode에서 index.js파일을 만들고 express 예제 코드를 아래와 같이 입력합니다.
const express = require('express')
const app = express()
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
app.listen(3000)

 

서버 실행 및 확인

  • vscode의 터미널에서 다음 코드를 입력합니다.
node index
  • 브라우저를 실행하고 주소창에 다음 url을 입력합니다.
http://localhost:3000
  • 브라우저 결과는 다음과 같습니다.

이상으로 express의 설치와 실행방법에 대해 알아보았습니다.

반응형
반응형

이 글의 동영상 강의 1편입니다.

https://youtu.be/560LIgIiU8g

다음은 동영상 강의 2편입니다.

https://youtu.be/LoZhQXs85r8

 

이 글은 NodeJS 공식 홈페이지의 다음 글을 참고하여 작성하였습니다.

https://nodejs.org/ko/docs/guides/anatomy-of-an-http-transaction/

 

HTTP 트랜잭션 해부 | Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 

NodeJS로 서버를 개발하려고 하려면 HTTP의 처리 과정을 이해하여야 합니다.

NodeJS에서 제공하는 http 모듈의 사용법과 같이 배워보도록 하겠습니다.

 

웹서버 만들기

  • 우선 웹서버 객체를 만듭니다.
const http = require('http');

const server = http.createServer((request, response) => {
});
  • 이때 사용된 createServer는 server 객체를 생성하고 발생한 이벤트를 전달하는 역할을 하므로 다음과 같이 변경할 수 있습니다.
const server = http.createServer();
server.listen(8080);
server.on('listening', () => {
   console.log(`listen on 8080 !!!`);
});

 

Request 처리하기

  • 생성한 서버에서 request를 받아 처리할 수 있습니다.
server.on('request', (request, response) => {
   console.log(request.headers);
   response.write('<h1>Node Server</h1>');
   response.end();
});
  • request에는 url, method, header 등의 정보가 포함됩니다.
server.on('request', (request, response) => {
  const { headers, method, url } = request;
  const userAgent = headers['user-agent'];
  console.log(`method : ${method}`);
  console.log(`url : ${url }`);
  console.log(`userAgent : ${userAgent}`);

  response.write('<h1>Node Server</h1>');
  response.end();
});
  • post나 put의 request에서 stream으로 전달되는 data와 end를 이용하면 body를 읽어올 수 있습니다.
  let body = [];
  request.on('error', (err) => {
    console.error(err);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    console.log(body);

    response.write('<h1>Node Server</h1>');
    response.end();
  });
  • 테스트를 위해서 postman에서 다음과 같이 변경 합니다.
    • request method를 GET에서 POST로 바꿉니다.
    • headers에 다음 값을 추가합니다.
      • Content-Type: application/json

  • Body탭에서 다음 항목을 변경합니다.
    • body type을 none에서 raw로 변경합니다.
    • data type을 JSON으로 변경합니다.

  • Send를 클릭하면 다음과 같은 결과를 확인할 수 있습니다.

  • request에서 error 이벤트를 받아 오류를 처리할 수 있습니다.
request.on('error', (err) => {
  // 여기서 `stderr`에 오류 메시지와 스택 트레이스를 출력합니다.
  console.error(err.stack);
});

 

Response 사용하기

  • statusCode를 이용해 상태 코드를 전달할 수 있습니다.
    지정하지 않을 경우의 상태코드는 항상 200입니다.
response.statusCode = 404; // 클라이언트에게 리소스를 찾을 수 없다고 알려줍니다.
  • setHeader를 이용해 header를 설정할 수 있습니다.
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');
  • 아래와 같이 명시적으로 header를 정의 할 수 있습니다.
response.writeHead(200, {
  'Content-Type': 'application/json',
  'X-Powered-By': 'bacon'
});
  • write와 end를 이용해 response body를 만들 수 있습니다.
response.write('<html>');
response.write('<body>');
response.write('<h1>Hello, World!</h1>');
response.write('</body>');
response.write('</html>');
response.end();
// 또는
response.end('<html><body><h1>Hello, World!</h1></body></html>');
  • respone에서 error event는 다음과 같이 처리할 수 있습니다.
response.on('error', (err) => {
  console.error(err);
});
  • 지금 까지의 내용을 정리하면 다음과 같이 코드를 작성할 수 있습니다.
const http = require('http');

http.createServer((request, response) => {
  const { headers, method, url } = request;
  let body = [];
  request.on('error', (err) => {
    console.error(err);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();

    response.on('error', (err) => {
      console.error(err);
    });

    response.writeHead(200, {'Content-Type': 'application/json'})
    const responseBody = { headers, method, url, body };
    response.end(JSON.stringify(responseBody))
  });
}).listen(8080);

에코 서버 만들기

  • 다음과 같이 /echo로 요청하는 post 메소드에 대해서 응답하는 서버를 만들 수 있습니다.
const http = require('http');

http.createServer((request, response) => {
  request.on('error', (err) => {
    console.error(err);
    response.statusCode = 400;
    response.end();
  });
  response.on('error', (err) => {
    console.error(err);
  });
  if (request.method === 'POST' && request.url === '/echo') {
    request.pipe(response);
  } else {
    response.statusCode = 404;
    response.end();
  }
}).listen(8080);

이상으로 nodejs의 http 요청을 처리하는 기본적인 방법에 대해 알아보았습니다.

 

반응형

+ Recent posts