자꾸 헷갈린다는 건 잘 모른다는 거겠지? 내가 몰라서 정리하는 기본 용어 💥💥💥

모든 코드는 아래와 같은 코드가 실행되는 중이라고 가정할 때이다.

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})


라우팅(Routing)

express 공홈에서 설명하는 라우팅은 아래와 같다.



라우팅은 URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에

애플리케이션이 응답하는 방법을 결정하는 것을 말합니다.

각 라우트는 하나 이상의 핸들러 함수를 가질 수 있으며, 이러한 함수는 라우트가 일치할 때 실행됩니다.

라우트 정의에는 다음과 같은 구조가 필요합니다.

이떄 app은 express의 인스턴스, METHOD는 HTTP 요청 메소드, PATH는 서버에서의 경로, HANDLER는 라우트가 일치할 때 실행되는 함수입니다.


`app.METHOD(PATH, HANDLER)`

(Node가 미들웨어로써의 역할을 하기 위해서 라우팅이 필요하다.)

예를 들어 사용자가 localhost:3000으로 접근한 후 /register에 대한 요청을 보냈을 때 (locallhost:3000/register)

register에 접근했을때 register.html 이라는 파일과 연결시킬수도 있고 다른 파일과 연결시키거나 다른 동작을 할수도 있다.

이 경우 어떤 동작을 할 것 인가에 대한 명령이 필요한데, 이게 라우팅이다.

(각 라우트는 하나 이상의 핸들러 함수를 가질수 있고, 이 함수는 라우트 함수가 일치할때 실행된다.)


이 링크에 들어가면, 직접 javascript로 라우터를 구현하며 자세한 설명이 나온다!


HTTP 요청 method

HTTP는 웹상에서 클라이언트와 서버 간에 요청/응답으로 데이터를 주고 받을 수 있는 프로토콜이다.

클라이언트가 HTTP 프로토콜을 통해 서버에게 요청을 보내면 서버는 요청에 맞는 응답을 클라이언트에게 전송하는데,

HTTP 요청에 포함되는 HTTP 메소드는 서버가 요청을 수행하기 위해 해야할 행동을 표시하는 용도로 사용한다.

method는 get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search 및 connect 등등 여러가지가 있다.

이 중에서 get, post가 제일 많이 쓰이고 또 차이첨이 자주 언급되는데, 말 나온 김에 정리해보자


GET

서버로부터 정보를 조회하기 위해 설계된 메소드; 요청해야할 데이터를 쿼리스트링에 담아서 전송.

GET은 불필요한 요청을 제한하기 위해 요청이 캐시될 수 있습니다.
js, css, 이미지 같은 정적 컨텐츠는 데이터양이 크고, 변경될 일이 적어서 반복해서 동일한 요청을 보낼 필요가 없습니다.
 정적 컨텐츠를 요청하고 나면 브라우저에서는 요청을 캐시해두고, 동일한 요청이 발생할 때 서버로 요청을 보내지 않고 캐시된 데이터를 사용합니다.
 그래서 프론트엔드 개발을 하다보면 정적 컨텐츠가 캐시돼 컨텐츠를 변경해도 내용이 바뀌지 않는 경우가 종종 발생합니다.
 이 때는 브라우저의 캐시를 지워주면 다시 컨텐츠를 조회하기 위해 서버로 요청을 보내게 됩니다.

출처: https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/

POST

리소스를 생성/변경하기 위해 설계된 메소드; 전송해야될 데이터를 HTTP 메세지의 Body에 담아서 전송

 POST 요청은 GET과 달리 대용량 데이터를 전송할 수 있습니다.
 이처럼 POST는 데이터가 Body로 전송되고 내용이 눈에 보이지 않아 GET보다 보안적인 면에서 안전하다고 생각할 수 있지만,
 POST 요청도 크롬 개발자 도구, Fiddler와 같은 툴로 요청 내용을 확인할 수 있기 때문에 민감한 데이터의 경우에는 반드시 암호화해 전송해야 합니다.

출처: https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/

첨부한 링크가 정말 설명을 잘 해두셨는데, get과 post의 가장 큰 차이는

GET은 Idempotent, POST는 Non-idempotent하게 설계되었다는 점이다.


GET이 Idempotent하도록 설계되었다는 것은 GET으로 서버에게 동일한 요청을 여러 번 전송하더라도 동일한 응답이 돌아와야 한다는 것을 의미합니다.
이에 따라 GET은 설계원칙에 따라 서버의 데이터나 상태를 변경시키지 않아야 Idempotent하기 때문에 주로 조회를 할 때에 사용해야합니다.
예를 들어, 브라우저에서 웹페이지를 열어보거나 게시글을 읽는 등 조회를 하는 행위는 GET으로 요청하게 됩니다.

반대로 POST는 Non-idempotent하기 때문에 서버에게 동일한 요청을 여러 번 전송해도 응답은 항상 다를 수 있습니다.
이에 따라 POST는 서버의 상태나 데이터를 변경시킬 때 사용됩니다. 게시글을 쓰면 서버에 게시글이 저장이 되고,
게시글을 삭제하면 해당 데이터가 없어지는 등 POST로 요청을 하게 되면 서버의 무언가는 변경되도록 사용됩니다.
이처럼 POST는 생성, 수정, 삭제에 사용할 수 있지만, 생성에는 POST, 수정은 PUT 또는 PATCH,
삭제는 DELETE가 더 용도에 맞는 메소드라고 할 수 있습니다.

출처: https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/


res.method()를 정리하면 아래와 같다.

  • res.download() 파일이 다운로드되도록 프롬프트합니다.
  • res.end() 응답 프로세스를 종료합니다.
  • res.json() JSON 응답을 전송합니다.
  • res.jsonp() JSONP 지원을 통해 JSON 응답을 전송합니다.
  • res.redirect() 요청의 경로를 재지정합니다.
  • res.render() 보기 템플리트를 렌더링합니다.
  • res.send() 다양한 유형의 응답을 전송합니다.
  • res.sendFile 파일을 옥텟 스트림의 형태로 전송합니다.
  • res.sendStatus() 응답 상태 코드를 설정한 후 해당 코드를 문자열로 표현한 내용을 응답 본문으로서 전송합니다.


middleware

middleware는 아래와 같으며,

응답 과정 중간에 껴서 어떠한 동작을 해주는 프로그램입니다. 익스프레스는 요청이 들어올 때 그에 따른 응답을 보내주는데요.
응답을 보내기 전에 미들웨어가 지정한 동작을 수행합니다. 전 시간에 보았던 express.static이 미들웨어의 한 종류로,
정적 파일의 기본 경로를 정해주는 역할을 합니다.

출처: https://www.zerocho.com/category/NodeJS/post/578b5a36d8316615006bee0f

응답을 보내기 전에 사용할 middleware를 app.use(미들웨어이름) 으로 보내주면 된다


HANDLER

express 공홈에서 설명하는 handler은 아래와 같다.

미들웨어와 비슷하게 작동하는 여러 콜백 함수를 제공하여 요청을 처리할 수 있습니다.
유일한 차이점은 이러한 콜백은 next('route')를 호출하여 나머지 라우트 콜백을 우회할 수도 있다는 점입니다.
이러한 메커니즘을 이용하면 라우트에 대한 사전 조건을 지정한 후, 현재의 라우트를 계속할 이유가 없는 경우에는 제어를 후속 라우트에 전달할 수 있습니다.
라우트 핸들러는 함수나 함수 배열의 형태 또는 둘을 조합한 형태일 수 있습니다.


오 정말 하나도 모르겠는데,,, 그래서 다시 handler를 구글링해봤다.

한 스레드는 그 내부의 연산만 가능하며 다른 스레드의 UI를 건드릴 수 없습니다.
 그런데 만약 스레드들이 서로 영향을 줄 수 없다면 스레드의 존재 이유가 없을 것입니다.

이를 해결하기 위해서 서로 다른 스레드 간의 참조를 위해서 스레드 간에 통신할 수 있는 장치를 만들었는데 그것이 핸들러[Handler]입니다.
 핸들러는 스레드 간에 메시지 객체나 러너블 객체를 통해 통신할 수 있는 장치이며,하나의 핸들러는 하나의 스레드와 관련을 맺습니다.
 핸들러는 자신이 생성된 스레드에 짝이 되며 다른 스레드와 통신을 수행하게 됩니다.

출처: https://csjung.tistory.com/43


예제 코드를 하나씩 자세히 살펴보면,


  1. 홈 페이지에서 Hello World!로 응답:
app.get('/', function (req, res) {
  res.send('Hello World!');
});
  1. 애플리케이션의 홈 페이지인 루트 라우트(/)에서 POST 요청에 응답:
app.post('/', function (req, res) {
  res.send('Got a POST request');
});
  1. /user 라우트에 대한 PUT 요청에 응답:
app.put('/user', function (req, res) {
  res.send('Got a PUT request at /user');
});
  1. /user 라우트에 대한 DELETE 요청에 응답:
app.delete('/user', function (req, res) {
  res.send('Got a DELETE request at /user');
});


app.route()

app.route()를 이용하면 라우트 경로에 대하여 체인 가능한 라우트 핸들러를 작성할 수 있다.

예를 들면

app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });

이렇게! 체인가능하다는 것은 시퀀셜하게 실행할 수 있다는 뜻 !

express.Router

공홈에는 아래와 같이 설명되어있다.


express.Router 클래스를 사용하면 모듈식 마운팅 가능한 핸들러를 작성할 수 있습니다.

Router 인스턴스는 완전한 미들웨어이자 라우팅 시스템이며, 따라서 “미니 앱(mini-app)”이라고 불리는 경우가 많습니다.


다음 예에서는 라우터를 모듈로서 작성하고, 라우터 모듈에서 미들웨어 함수를 로드하고, 몇몇 라우트를 정의하고,
기본 앱의 한 경로에 라우터 모듈을 마운트합니다.

코드와 주석을 보면 이해가 될 것이다.

// birds.js

var express = require('express');
var router = express.Router();

// middleware that is specific to this router
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});
// define the home page route
router.get('/', function(req, res) {
  res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
  res.send('About birds');
});

module.exports = router;

// 이후 앱 내에서 라우터 모듈 로드
var birds = require('./birds');
...
app.use('/birds', birds);

앱은 이제 /birds 및 /birds/about에 대한 요청을 처리할 수 있게 되었으며,

해당 라우트에 대한 특정한 미들웨어 함수인 timeLog를 호출할 것이다.


reference

  • https://expressjs.com/ko/starter/basic-routing.html

  • https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/