[Node.js] 3. express

rin·2020년 12월 13일
3

Document 번역

목록 보기
22/22
post-thumbnail

https://expressjs.com Guide 섹션을 번역합니다.

Routing

개념

라우팅은 클라이언트 요청에 대해 어플리케이션의 앤드포인트(URIs)가 응답하는 방식을 나타낸다.

HTTP 메서드에 해당하는 Express App 컴포넌트의 메서드를 사용해 라우팅을 정의한다. 첫번째 인자로는 지정된 경로(URI)를 두번째 인자로는 호출될 콜백 함수를 지정한다.

  • app.get()
  • app.post()
  • app.put()
  • app.delete()
  • app.all() : 모든 HTTP 메서드 처리
  • app.use() : 미들웨어를 콜백함수로 지정

라우팅 메서드는 둘 이상의 콜백 함수를 인수로 가질 수 있는데, 콜백함수가 여러개인 경우 next 인수로 제공한 다음 함수를 콜백 함수 내에서 호출하여 다음 콜백으로 넘겨준다. (next();)

const nextCallback = text => {
    console.log(text);
}

app.get('/next', (req, res, nextCallback) => {
    console.log('first callback');
    nextCallback('call second callback function');    
});

Route paths

요청 메소드와 결합된 라우트 패스는 요청이 이루어질 수 있는 엔드포인트를 정의한다.
라우트 패스는 문자열, 문자열 패턴, 정규식일 수 있다.

  • ?, +, *, () 와 같은 문자는 정규표현식에 대응되는 요소들이다.
  • -, . 는 문자열 기반 경로로써 문자 그대로 해석된다.
  • $ 문자를 문자열 경로로 사용하려면 [] 내부에 사용하도록한다.
    • 예를 들어 /data/$book/data/[\$]book 으로 표현한다.

❗️ NOTE
Express는 라우터 패스에 매칭하기위해 path-to-regexp를 사용한다.

또한, 쿼리 문자열은 라우트패스의 일부가 아니다.

/* 문자열 기반 ***/
// /about
app.get('/about', (req, res) => {
  ...
});
  
// . 기호는 문자 그대로 해석된다
// /random.text
app.get('/random.text', (req, res) => {
  ...
});

/* 문자열 패턴 기반 ***/
// /abc, /abcd
app.get('/ab?cd', (req, res) => {
  ...
});

// /abcd, /abbcd, /abbbcd ...
app.get('/ab+cd', (req, res) => {
  ...
});

// /abcd, /abxcd, /abRANDOMcd, /ab123cd ...
app.get('/ab*cd', (req, res) => {
  ...
});

// /abe, /abcde
app.get('/ab(cd)?e', (req, res) => {
  ...
});

/* 정규식 기반 ***/
// a가 존재하는 모든 경로
app.get('/a/', (req, res) => {
  ...
});

// /butterfly, /dragonfly은 가능하다.
// /butterflyman, /dragonflyman 은 불가하다.  
app.get('/.*fly$/', (req, res) => {
  ...
});

Route parameters

Route parameter는 URL의 해당 위치에 지정된 값을 가져오는데에 사용되는 URL 세그먼트이다. 이 값은 req.params 에 key:value로 저장된다.

app.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)
})

// 요청
Request URL: http://localhost:3000/users/34/books/8989
// req.params: { "userId": "34", "bookId": "8989" }

하이픈-과 온점.은 문자 그대로 해석되므로 다음과 같이 라우트 파라미터와 함께 사용할 수 있다.

## 하이픈 사용 예시
Route path: /flights/:from-:to
Request URL: http://localhost:3000/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }

## 온점 사용 예시
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }

정확한 문자열을 제어하기 위해 괄호()에 정규표현식을 추가할 수 있다.

Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}

Route handlers

요청 처리를 위해 미들웨어처럼 작동하는 여러 콜백함수를 제공할 수 있다.

예외적으로 next(route)와 같이 나머지 라우트 콜백을 바이패스하기 위해 호출되기도 한다. 이 메커니즘을 사용하여 패스에 사전 조건을 적용한 다음 현재 패스로 진행할 필요가 없는 것들은 후속 패스에 제어권을 전달할 수 있다.

라우트 핸들러는 함수, 함수배열, 함수+함수배열 형태일 수 있다.

// 단일 콜백 함수
app.get('/example/a', (req, res) => {
  ...
});
  
// 둘 이상의 콜백 함수
app.get('/example/b',
(req, res, next) => {
  ...
  next();
}, (req, res) => {
  ...
});
  
// 배열로 이뤄진 콜백 함수
var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

var cb2 = function (req, res) {
  res.send('Hello from C!')
}

// 배열 앞부분 함수부터 호출되고, 그 다음 인덱스의 함수가 현재 함수의 next에 전달된다.
app.get('/example/c', [cb0, cb1, cb2]);
  
// 독립적인 함수와 함수 배열의 조합
var cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

var cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

app.get('/example/d', [cb0, cb1], function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from D!')
})
// console 출력은 다음과 같다.
// CB0 CB1 the response will be sent by the next function ... Hello from D!

Response methods

다음과 같은 response 오브젝트(res)의 메소드를 실행함으로써 클라이언트에 응답을 보내고 요청을 종료할 수 있다. (만약 Route handler에서 해당 메소드 중 어떤것도 호출되지 않으면 클라이언트에 어떤 응답도 보내지않고 요청이 중단되므로 클라이언트는 대기상태로 머무른다.)

methoddescription
download다운로드할 파일을 프롬프트한다.
end응답 프로세스를 종료한다.
jsonJSON 응답을 전달한다.
jsonpJSONP를 지원하는 JSON 응답을 전달한다.
redirect요청을 리다이렉트한다.
render뷰 템플릿을 렌더링한다.
send다양한 유형으로 응답한다.
sendFile파일을 octet 스트림으로 전달한다.
sendStatus응답 상태 코드를 설정하고 해당 상태의 문자열 표현을 응답 body에 실어보낸다.

app.route()

express.Router를 사용하여 마운트 가능한 라우트 랜들러인 모듈러를 만들 수 있다. Router 인스턴스는 완전한 미들웨어이자 라우팅 시스템이다. (종종, mini-app 이라고 불리기도 한다.)

다음 예제는 내부에 미들웨어 함수를 로드하는 라우터 모듈을 만들고, 일부 경로를 정의한 뒤 메인 앱의 경로에 라우터 모듈을 마운트한다.

// birds.js
var express = require('express');
var router = express.Router();

router.use((req, res, next) => {
    console.log('Time : ', Date.now());
    next();
})

router.get('/birds', (req, res) => {
    console.log('birds');
    res.send('birds');
});

router.get('/birds/about', (req, res) => {
    console.log('birds/about');
    res.send('birds/about');
});

module.exports = router;

// app.js
const express = require('express');
const app = express();
const port = 5555;
const birds = require('./birds');

app.use(birds);
... (이하생략)

만약 app.js에 app.get(...) 과 같이 라우트가 정의되어 있어도 birds.js에서 정의된 미들웨어를 거치게된다. 요청은 정상적으로 받아들여진다.

profile
🌱 😈💻 🌱

0개의 댓글