Express 로 서버 구현하기

345·2022년 11월 18일
1

Express 공식문서

위 사이트에 기재된 API 문서를 참고하여 Express 웹 어플리케이션을 만들 수 있습니다.
나만의 웹 서버를 만들어봅시다.

🔥 Express 서버 구현

import express from "express";
// 바벨을 세팅하지 않았다면, const express = require("express") 라고 작성!

const app = express();
// express app 만들기 -> 서버!

const PORT = 4000;
// 포트 넘버 지정

const handleHome = (req, res) => {
	return res.send("This is Home.");
}
// req 와 res 는 함수 호출 시 자동으로 보내지는 매개변수
// 요청에 대해 응답 반환
// res.send("content") => 요청에 대한 응답으로 메시지를 보냄 

app.get('/', handleHome);
// 브라우저가 루트 페이지로 접속하며 루트 페이지에 대해 get 요청을 할때 라우팅
// get 요청에 대한 처리 콜백함수 handleHome

app.listen(PORT)
// 포트 번호로 연결

express 를 얻어온 후 실행하면 app 이 만들어집니다.
만들어진 app 은 클라이언트에게 서비스를 제공하는 서버라고 볼 수 있습니다.

listen() 메소드로 app 에 포트 번호를 넘겨주면, 서버가 클라이언트와 통신하는데 해당 포트를 사용합니다.

우리 서버는 내 컴퓨터 localhost 의 4000번 포트를 통해 통신합니다.
우리는 이에 접속하기 위해 http://localhost:4000 이라는 주소를 브라우저에 넘깁니다.

브라우저 : localhost의 4000번 포트의 서버 프로그램과 통신하는군요?

이렇게 됩니다.

우리가 접속을 요청하면, 브라우저는 접속하려는 페이지 정보를 받아오기 위해 서버에게 요청을 보냅니다

이 때, 브라우저가 보내는 요청이 GET 입니다.

http://localhost:4000 는 사실 http://localhost:4000/ 이고, "/" (루트) 페이지이죠.

브라우저는 "/" 에 해당하는 정보를 서버에게 받아와서 사용자에게 보여줍니다.
브라우저가 보낸 GET 요청에 대해, 서버가 응답을 해줘야 우리가 결과를 볼 수 있습니다.

서버가 GET 요청에 응답하지 않는다면 브라우저는 계속 대기하다가 응답을 못 받았다고 오류 메시지를 띄우겠죠?

📌 app.get()

get() 메소드는 브라우저가 페이지에 대해 GET 요청을 했을 때, 이에 대한 응답을 처리합니다.

const handleLogin = (req, res) => {
	return res.send("Login Page");
}
// req, res 변수를 받아 요청에 응답

app.get("/login", handleLogin);
// http://localhost:4000/login 페이지 요청에 대한 처리를 handleLogin 에서 처리
// handleLogin 은 /login 에 대한 controller

경로에 대한 GET 요청을 컨트롤러 에 맡깁니다.

컨트롤러(콜백함수) 에서는 요청과 응답에 대한 두 변수를 자동으로 받아오고,
요청에 응답하면 브라우저가 GET 에 대한 결과를 얻을 수 있습니다.

📌 미들웨어 (middleware)

미들웨어는 브라우저가 요청을 한 후 서버가 응답하기까지의 절차에서,
요청과 응답 사이에 존재하는 소프트웨어 를 의미합니다. (middle software)

const myMiddleware = (req, res, next) => {
	console.log("This is Middleware.");
    next(); // 다음 함수를 실행
}

const handleHome = (req, res, next) => {
	return res.send("This is Home.");
}

app.get('/', myMiddleware, handleHome);
// get 으로 요청을 보내고
// handleHome 에서 응답을 하기 전에
// myMiddleware 를 거치고 있음

함수가 자동으로 받는 매개변수는 req, res, next 가 있습니다.

req 는 요청에 대한 object, res 는 응답에 대한 object, 그리고 next 는 다음에 존재하는 함수 변수이죠.

next 에 해당하는 함수는 myMiddleware 의 경우 handleHome 입니다.
handleHome 의 경우 get() 안에 제일 마지막에 있으므로 next 에 해당하는 함수가 없습니다.

따라서 handleHome 은 마지막 차례에 오는, finalware 라고 할 수 있습니다.
return 으로 응답을 하며 연결을 종료하는, 마지막으로 호출되는 함수이니까요.

즉, 요청과 응답 사이에 있다면 어떤 controller 든지 미들웨어가 될 수 있습니다.

const myMiddleware = (req, res, next) => {
	console.log("This is Middleware.");
    next(); 
}

const handleHome = (req, res) => {
	return res.send("This is Home.");
}
// finalware 이므로 next 가 없어도 됨!

app.get('/', myMiddleware, handleHome);

handleHome 은 컨트롤러로써 마지막에 호출되므로 next 를 받지 않아도 됩니다.

const myMiddleware = (req, res, next) => {
	console.log("This is Middleware.");
    return res.send("This is END.");
    // 미들웨어에서 먼저 응답을 끝내버리면...?
    next(); // next 함수는 실행되지 않음!
}

const handleHome = (req, res) => {
	return res.send("This is Home.");
}

app.get('/', myMiddleware, handleHome);

미들웨어가 먼저 응답을 return 하면 get() 이 종료되어 next 함수도 실행되지 않게 됩니다.

✅ app.use()

지정된 경로에 미들웨어가 적용되게 하고 싶을 때 사용합니다.

app.use(path, callback) 

이와 같은 형태로, 요청한 URL 경로의 루트가 path 와 일치할 때 미들웨어가 적용됩니다.

path 의 기본은 "/" 루트 경로입니다.
루트는 모든 경로의 시작점으로, 경로들은 루트에서 뻗어나온다고 볼 수 있습니다.

따라서 path 를 따로 지정하지 않고 기본 세팅대로 "/" 가 적용 되게 하면,
모든 라우트에 미들웨어가 적용 됩니다.

app.use(myMiddleware);
// 맨 위에 use() 위치

app.get("/", handleHome);
app.get("/login", handleLogIn);
// "/" 와 "/login" 의 라우터 모두에 myMiddleware 미들웨어 적용

app.use() 를 최상단에 두면 이하의 모든 get() 의 경로에 미들웨어가 적용됩니다.

app.get("/", handleHome);
// 미들웨어 적용되지 않음

app.use(myMiddleware);
// 중간에 use() 위치

app.get("/login", handleLogIn);
// 미들웨어 적용

use() 이전에 작성된 get() 의 경로에는 미들웨어가 적용되지 않습니다.

app.use(myMiddleware, secondMiddleware);
// 미들웨어 여러개 사용

app.get("/", handleHome);
app.get("/login", handleLogIn);

여러 개의 미들웨어가 적용되게 할 수도 있습니다.

미들웨어 가져다 쓰기

직접 작성하지 않아도, 누가 이미 만들어놓은 미들웨어를 가져다 사용할 수도 있습니다.

morgan 을 사용해봅시다.

npm i morgan 

으로 morgan을 설치하고

import morgan from "morgan";
// 바벨 적용을 안했다면 const morgan = require("morgan");
// morgan 가져오기

const logger = morgan("dev");
// morgan(option) 이 옵션에 맞는 함수를 반환해줌
// logger 에는 반환된 함수가 들어감

app.use(logger);
// 미들웨어 적용!

morgan 을 가져와 morgan(option) 을 해주면 옵션에 맞는 함수를 반환해줍니다.

profile
기록용 블로그 + 오류가 있을 수 있습니다🔥

0개의 댓글