[TIL] 211121

Lee SyongΒ·2021λ…„ 11μ›” 21일
0

TIL

λͺ©λ‘ 보기
95/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. middlewares - controller / app.use() / Morgan

  2. routers - λΌμš°ν„° λ§Œλ“€κ³  μ‚¬μš©ν•˜κΈ°


πŸ“š 배운 것

1. middlewares

1) middleware와 controller

middlewaresλž€ λΈŒλΌμš°μ €μ˜ requests와 μ„œλ²„μ˜ responses의 쀑간에 μžˆλŠ” μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό λ§ν•œλ‹€.

μ•žμ—μ„œ μ‚¬μš©ν–ˆλ˜ handler ν•¨μˆ˜λŠ” 사싀 controller라고 λΆˆλ¦°λ‹€.
λͺ¨λ“  controllerλŠ” middlewareκ°€ 될 수 있고, λ§ˆμ°¬κ°€μ§€λ‘œ λͺ¨λ“  middleware도 contollerκ°€ 될 수 μžˆλ‹€.
controllerκ°€ next() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€λ©΄, κ·Έ controllerλŠ” middlewareκ°€ λœλ‹€.

middlewareλŠ” request에 μ‘λ‹΅ν•˜μ§€ μ•Šκ³ , requestλ₯Ό μ§€μ†μ‹œμΌœμ€€λ‹€.
middlewareλŠ” μ‚¬μš©μžκ°€ μ›Ή μ‚¬μ΄νŠΈμ˜ μ–΄λ””λ₯Ό κ°€λ €κ³  ν•˜λŠ”μ§€ λ§ν•΄μ£ΌλŠ” ν•¨μˆ˜λ‘œ, ν•„μš”ν•œ 만큼 λ§Œλ“€μ–΄ μ‚¬μš©ν•  수 μžˆλ‹€.

const loggerMiddleware = (req, res, next) => { // controller이자 middleware
  console.log(`Someone is going to: ${req.url}`):
  next();
}

const handleHome = (req, res) => { // controller
  return res.send("Hello!");
};

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

λΈŒλΌμš°μ €κ°€ root νŽ˜μ΄μ§€λ₯Ό 갖닀달라고 μš”μ²­ν•˜λ©΄ expressλŠ” loggerMiddleware ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
console에 req.url 즉, μ‚¬μš©μžκ°€ μ›Ή μ‚¬μ΄νŠΈμ—μ„œ κ°€λ €κ³  ν•˜λŠ” url이 좜λ ₯λœλ‹€.
κ·Έ ν›„, next()에 μ˜ν•΄ λ‹€μŒ handleHome ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.
res.send("Hello!")κ°€ μ‹€ν–‰λ˜μ–΄ 화면에 λ©”μ‹œμ§€κ°€ λœ¨λ©΄μ„œ requestκ°€ μ’…λ£Œλœλ‹€.

κ·ΈλŸ¬λ‚˜, μœ„μ˜ middlewareλŠ” ν•˜λ‚˜μ˜ urlμ—λ§Œ μ μš©λ˜μ–΄ μžˆμ–΄ λ³„λ‘œ μ“Έλͺ¨κ°€ μ—†λ‹€.
이λ₯Ό 고쳐보자.

2) app.use(middleware)

μ–΄λŠ url에도 μž‘λ™ν•˜λŠ” global middlewareλ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

μˆœμ„œκ°€ μ€‘μš”ν•˜λ‹€. app.use()κ°€ λ¨Όμ € 온 후에 app.get()이 와야 ν•œλ‹€.
λ§Œμ•½ app.use()κ°€ μ–΄λ–€ routeλ₯Ό 인자둜 κ°€μ§€λŠ” app.get()보닀 뒀에 μ˜¨λ‹€λ©΄ κ·Έ middlewareλŠ” κ·Έ routeμ—λŠ” μž‘λ™ν•˜μ§€ μ•ŠλŠ”λ‹€.

const loggerMilddleware = (req, res, next) => {
  console.log(`Someone is going to: ${req.url}`); // req.url === req.path
  next();
};

const handleHome = (req, res) => {
  return res.send("Hello!");
};

const handleLogin = (req, res) => {
  return res.end();
};

app.use(loggerMilddleware);
app.get("/", handleHome);
app.get("/login", handleLogin);

νŒŒμΌμ„ μœ„μ™€ 같이 μˆ˜μ •ν•œ ν›„ μ €μž₯ν•œλ‹€.

localhost:4000 에 λ“€μ–΄κ°€λ©΄, μ½˜μ†”μ— 'Someone is going to: /'이 λœ¬λ‹€.
localhost:4000/login 에 λ“€μ–΄κ°€λ©΄, μ½˜μ†”μ— 'Someone is going to: /login'이 λœ¬λ‹€.

ν•œνŽΈ localhost:4000/aaaaa 에 λ“€μ–΄κ°€λ©΄, μ„œλ²„κ°€ 이 url을 μΈμ‹ν•˜μ§€ λͺ»ν•˜λ―€λ‘œ ν™”λ©΄μ—λŠ” 'Cannot GET /aaaa'κ°€ λœ¨μ§€λ§Œ μ½˜μ†”μ—λŠ” 'Someone is going to: /aaaa'이 λœ¬λ‹€.

즉, μ–΄λŠ url이 get request λ˜μ—ˆλ“  간에 일단 global middlewareλŠ” λͺ¨λ“  routeμ—μ„œ 싀행됨을 μ•Œ 수 μžˆλ‹€.

3) privateMiddleware

const loggerMilddleware = (req, res, next) => {
  // μ–΄λ–€ request methodκ°€ μ–΄λ–€ url둜 ν–₯ν•˜λŠ”μ§€ μ•Œ 수 μžˆλ„λ‘ μ½”λ“œλ₯Ό μˆ˜μ •ν–ˆλ‹€
  console.log(`${req.method} ${req.url}`);
  next();
};

const privateMiddleware = (req, res, next) => {
  const url = req.url;
  if (url === "/protected") {
    return res.send("<h1>Not Allowed</h1>");
  }
  console.log("Allowed, you may continue.");
  next();
};

const handleHome = (req, res) => {
  return res.send("Hello!");
};

const handleProtected = (req, res) => {
  return res.send("Welcome to the private lounge.");
};

app.use(loggerMilddleware);
app.use(privateMiddleware);
// app.use(loggerMiddleware, privateMiddleware); 라고 적어도 됨
app.get("/", handleHome);
app.get("/protected", handleProtected);

localhost:4000/protected 에 λ“€μ–΄κ°€λ©΄, μ½˜μ†”μ—λŠ” loggerMiddleware ν•¨μˆ˜μ— μ˜ν•΄ 'GET /protected'κ°€ 뜨고, ν™”λ©΄μ—λŠ” privateMiddleware ν•¨μˆ˜μ— μ˜ν•΄ 'Not Allowed'κ°€ λœ¬λ‹€.
즉, privateMiddleware ν•¨μˆ˜μ˜ if 쑰건식을 λ§Œμ‘±ν•˜μ—¬ requestλ₯Ό μ§€μ†ν•˜λŠ” middlewareκ°€ requestλ₯Ό μ’…λ£Œν•˜λŠ” controllerκ°€ 된 것이닀.

4) Morgan μ„€μΉ˜ (μ™ΈλΆ€ 미듀웨어 μ„€μΉ˜)

β€» npm - morgan μ°Έκ³ 

Morgan은 무슨 일이 μ–΄λ””μ—μ„œ μΌμ–΄λ‚¬λŠ”μ§€λ₯Ό κΈ°λ‘ν•˜λŠ” 데 도움을 μ£ΌλŠ” node.js 용 request logger middleware이닀.
VS code λ‚΄μž₯ 터미널에 'npm i morgan'을 μž…λ ₯ν•΄ μ„€μΉ˜ν•  수 μžˆλ‹€.
morgan() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄μ„œ 섀정을 ν•΄μ€˜μ•Ό ν•œλ‹€.

import morgain from "morgan";

const logger = morgan("dev");

const handleHome = (req, res) => {
  return res.send("Hello!");
};

app.use(logger);
app.get("/", handleHome);

morgan() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, req, res, 'next'λ₯Ό ν¬ν•¨ν•œ middlewareλ₯Ό return ν•œλ‹€.
ν•¨μˆ˜μ˜ 인자둜 λ“€μ–΄κ°„ "dev"λŠ” middlewareλ₯Ό μ„€μ •ν•΄μ€€λ‹€. dev, combined, tiny, common, short의 5가지 μ˜΅μ…˜μ„ 넣을 수 μžˆλŠ”λ° μ˜΅μ…˜λ§ˆλ‹€ 각각 μ½˜μ†”μ—μ„œ λ³΄μ—¬μ£ΌλŠ” 것이 λ‹€λ₯΄λ‹€.


2. routers

μ‹€μ œλ‘œ wetube μ½”λ”© μ‹œμž‘ ❗

1) router(λΌμš°ν„°)λž€?

ν”„λ‘œμ νŠΈμ—μ„œ μ–΄λ–€ μ’…λ₯˜μ˜ 데이터λ₯Ό μ΄μš©ν•  것인지 생각해야 ν•œλ‹€.
wetube ν”„λ‘œμ νŠΈμ—μ„œλŠ” 크게 두 κ°€μ§€μ˜ 데이터λ₯Ό 닀룬닀.
첫 λ²ˆμ§ΈλŠ” 'λΉ„λ””μ˜€(μ˜μƒ)'이고, 두 λ²ˆμ§ΈλŠ” 'user(μ‚¬μš©μž)'이닀.
이λ₯Ό wetube ν”„λ‘œμ νŠΈμ˜ 도메인이라고 ν•  수 μžˆλ‹€.

이λ₯Ό url μ°¨μ›μ—μ„œ 생각해보면, μ•„λž˜μ™€ 같은 url 리슀트λ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

πŸ’‘ κΈ€λ‘œλ²Œ λΌμš°ν„°

/ β†’ Home
/join β†’ Join νŽ˜μ΄μ§€
/login β†’ Login νŽ˜μ΄μ§€
/search β†’ Search νŽ˜μ΄μ§€

πŸ’‘ user λΌμš°ν„°

/users/edit β†’ Edit user νŽ˜μ΄μ§€
/users/delete β†’ Delete user νŽ˜μ΄μ§€

πŸ’‘ video λΌμš°ν„°

/videos/watch β†’ Watch video νŽ˜μ΄μ§€
/videos/edit β†’ Edit video νŽ˜μ΄μ§€
/videos/delete β†’ Delete video νŽ˜μ΄μ§€
/videos/comments β†’ comment on a video νŽ˜μ΄μ§€
/videos/comments/delete β†’ Delete a comment of a video νŽ˜μ΄μ§€

router(λΌμš°ν„°)λž€ μž‘μ—… 쀑인 주제λ₯Ό 기반으둜 url을 κ·Έλ£Ήν™”ν•˜λŠ” 것을 λ§ν•œλ‹€.

λΌμš°ν„°λŠ” 도메인(이 경우, video와 user) λ³„λ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.
예λ₯Ό λ“€μ–΄, /videos둜 μ‹œμž‘ν•˜λŠ” λͺ¨λ“  url듀은 'video λΌμš°ν„°'λΌλŠ” ν•˜λ‚˜μ˜ λΌμš°ν„°λ‘œ κ·Έλ£Ήν™”ν•  수 μžˆλ‹€.

2) global router(κΈ€λ‘œλ²Œ λΌμš°ν„°)

κΈ€λ‘œλ²Œ λΌμš°ν„°λŠ” ν™ˆμ—μ„œ λ°”λ‘œ 갈 수 μžˆλŠ” νŽ˜μ΄μ§€λ“€μ„ λ‹΄κ³  μžˆλ‹€

/ β†’ Home
/join β†’ Join νŽ˜μ΄μ§€
/login β†’ Login νŽ˜μ΄μ§€
/serch β†’ Search νŽ˜μ΄μ§€

사싀 μœ„μ—μ„œ 배운 λŒ€λ‘œλΌλ©΄ μœ„ url듀은 κ·œμΉ™μ— μ–΄κΈ‹λ‚œ λ“― 보인닀.
joinκ³Ό login을 ν•˜λŠ” 것은 user이고 search λ˜λŠ” 것은 videos라면, url은 μ•„λž˜μ²˜λŸΌ λ˜μ–΄μ•Ό ν•˜μ§€ μ•Šμ„κΉŒ?

/
/users/join
/users/login
/videos/search

κ·ΈλŸ¬λ‚˜ μ‹€μ œλ‘œ 보톡은 μ΄λ ‡κ²Œ url을 λ§Œλ“€μ§€ μ•ŠλŠ”λ‹€.
url을 κΉ”λ”ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄ 가끔은 κ·œμΉ™μ„ μ–΄κΈ°κ³  μ˜ˆμ™Έλ₯Ό λ§Œλ“€κΈ°λ„ ν•œλ‹€.

3) router λ§Œλ“€κ³  μ‚¬μš©ν•˜κΈ°

(1) express.Router()

μ•„λž˜μ™€ 같이 μ„Έ 개의 λΌμš°ν„°λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

const globalRouter = express.Router();
const userRouter = express.Router();
const videoRouter = express.Router();

(2) app.use("루트 url", λΌμš°ν„° 이름)

λΌμš°ν„°λ₯Ό λ§Œλ“  ν›„ μ‚¬μš©ν•˜κΈ° μœ„ν•΄ 섀정을 ν•΄μ•Ό ν•œλ‹€

app.use("/", globalRouter);
app.use("/users", userRouter);
app.use("/videos", videoRouter);

첫 번째 인자둜 '루트 url'을, 두 번째 인자둜 'λΌμš°ν„° 이름'을 κ°€μ Έμ˜¨λ‹€.
μ΄λ•Œ 루트 urlμ΄λž€ κΈ€λ‘œλ²Œ λΌμš°ν„°μ˜ 경우 '/'λ₯Ό, user λΌμš°ν„°μ˜ 경우 '/users'λ₯Ό, video λΌμš°ν„°μ˜ 경우 '/videos'λ₯Ό μ˜λ―Έν•œλ‹€.

이제 우리의 앱은 λ‹€λ₯Έ url을 이해할 μ€€λΉ„κ°€ λ˜μ—ˆλ‹€.

(3) 각 λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€ λ§Œλ“€κΈ°

이λ₯Ό λ°”νƒ•μœΌλ‘œ 각각의 λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€λ₯Ό λ§Œλ“€ 수 μžˆλ‹€.
μž„μ˜λ‘œ κΈ€λ‘œλ²Œ λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€λŠ” '/(즉, Home)'둜 ν•˜κ³ , user λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€λŠ” 'users/edit'으둜 ν•˜κ³ , video λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€λŠ” '/videos/watch'둜 ν•˜κΈ°λ‘œ ν•œλ‹€.

πŸ”Ž μ½”λ“œ

// λΌμš°ν„° λ§Œλ“€κΈ°
// controller μ •μ˜
// Router.get("λΌμš°ν„°μ˜ 첫 νŽ˜μ΄μ§€ url", controller);

const globalRouter = express.Router();
const handleHome = (req, res) => res.send("Home");
globalRouter.get("/", handleHome);

const userRouter = express.Router();
const handleEditUser = (req, res) => res.send("Edit User");
userRouter.get("/edit", handleEditUser);

const videoRouter = express.Router();
const handleWatchVideo = (req, res) => res.send("Watch Video");
videoRouter.get("/watch", handleWatchVideo);

app.use("/", globalRouter);
app.use("/users", userRouter);
app.use("/videos", videoRouter);

πŸ”Ž κ²°κ³Ό

λΈŒλΌμš°μ €μ˜ μ£Όμ†Œ 창에 localhost:4000/ 이라고 μž…λ ₯ν•΄ λ“€μ–΄κ°€λ©΄, 화면에 Home 이라고 λœ¬λ‹€.
λΈŒλΌμš°μ €μ˜ μ£Όμ†Œ 창에 localhost:4000/users/edit 라고 μž…λ ₯ν•΄ λ“€μ–΄κ°€λ©΄, 화면에 Edit User 라고 λœ¬λ‹€.
λΈŒλΌμš°μ €μ˜ μ£Όμ†Œ 창에 localhost:4000/videos/watch 라고 μž…λ ₯ν•΄ λ“€μ–΄κ°€λ©΄, 화면에 Watch Video 라고 λœ¬λ‹€.

무슨 일이 μΌμ–΄λ‚œ 걸까?
video λΌμš°ν„°λ₯Ό μ˜ˆμ‹œλ‘œ λ“€μ–΄ μ„€λͺ…해보겠닀.

πŸ”Ž μ„€λͺ…

const videoRouter = express.Router(); // 2
const handleWatchVideo = (req, res) => res.send("Watch Video"); // 3
videoRouter.get("/watch", handleWatchVideo); // 2, 3

app.use("/videos", videoRouter); // 1
  1. λˆ„κ΅°κ°€ /videos둜 μ‹œμž‘ν•˜λŠ” url을 찾으면(이 κ²½μš°μ—λŠ” μ‚¬μš©μžκ°€ /videos/watch λ₯Ό μž…λ ₯ν–ˆλ‹€κ³  ν•˜μž.), expressλŠ” video λΌμš°ν„° μ•ˆμœΌλ‘œ λ“€μ–΄κ°„λ‹€.

  2. expressλŠ” video λΌμš°ν„° μ•ˆμ—μ„œ μ‚¬μš©μžκ°€ μž…λ ₯ν•œ url의 λ‚˜λ¨Έμ§€ μ£Όμ†Œ(즉, /watch)λ₯Ό μ°ΎλŠ”λ‹€. video λΌμš°ν„°λŠ” /watch λΌλŠ” 1가지 루트λ₯Ό κ°€μ§€λ―€λ‘œ μš°λ¦¬λŠ” /videos μ•ˆμ˜ /watch 에 있게 λœλ‹€.

  3. κ·Έ λ‹€μŒμ— expressκ°€ handleWatchVideo ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•¨μœΌλ‘œμ¨ ν™”λ©΄μ—λŠ” Watch Videoκ°€ ν‘œμ‹œλœλ‹€.


✨ 내일 ν•  것

  1. κ°•μ˜ 계속 λ“£κΈ°
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€