Express + Router

길고 꾸준하게·2022년 5월 11일
0

Node.js퍼먹기

목록 보기
3/5
post-thumbnail

1. 라우팅 (Routing)

라우팅은 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식

자세히 뜯어서 봐보자면.

  1. 특정경로(url등) 및 특정한 http 요청 메소드(get,post등)인 특정 엔드포인트에 대한 클라이언트 요청에
  2. application이 응답(response)하는 방법을 결정하는 것.

즉 어떤 경로 + 요청에 어떻게 응답할지를 정하는것. => 전 포스팅에 썻던내용들이 라우팅.

우리가 했던 app.get('/path',controllerFun)이 과정이 모두다 '라우팅' 과정 이었던 것이고. 이것들 하나하나가 '라우트(Route)'라고 불린다.
=> 어째 전 포스팅에 써져있어야 했던것같긴한데..

1-1. 라우트의 구조

app.httpMethod(path,handler)
  • app : express의 인스턴스.
  • httpmethod : 말그대로. ex) get post delete put등
  • path : 서버에서의 경로
  • handler : path가 일치할때 실행되는 함수.

2. 라우터 (Router) in express

미들웨어 및 라우팅 기능만 수행할수 있는 '미니 어플리케이션' 느낌.
최상위 express object에 Router를 만드는 Router() 메서드가 있다.

Router는 MiddleWare자체처럼 작동하기 때문에 app.use() or 또다른 Router의 use() 메서드로 사용할수 있다.

=> 나만의 이해

  • url이 어떻게 시작하는지에 따라 나누는 방법(일단은 이렇게 이해)
  • 공통시작부분(ex:/users)으로 그룹화

2-1 라우터 생성 & 사용

import express from "express" //babel
const app = express();

//최상위 express object에 있다고 했으니
const router = express.Router('/path')
//미들웨어 처럼 작동하기 때문에 use를 이용해 path와 match시켜서 사용해야함

app.use('/path',router);
//미들웨어처럼 작동? => 결국 response를 return하는 컨트롤러가 존재해야함. => 라우팅

router.get('/route',routeHandler);
* /path/route
  1. app.use(path,router) : path로 요청이 오면 라우터가 실행될거고.
    라우터안에서 컨트롤러함수를 찾을거다. (router는 미들웨어다. 컨트롤러함수를 찾아서 res를 return해야하니까)
  2. router.get(path,handler) : 라우터 안에서 라우트를 해주고, 해당 path에 요청이 오면 컨트롤러함수를 실행할거다

2-2 하지만 라우터와 컨트롤러를 섞어쓰는건 좋지않다.

왜냐면 컨트롤러는 함수고, 라우터는 그 컨트롤러함수를 이용하는쪽이니까.
-> 엄연히 다른기능을 수행하니까 분리를 하자는거다
-> 각각의 기능을 수행하는 폴더를 만들어서 모듈화를 해서 import/export해서 쓰는게 좋다.

import express from 'express'

// in main

import {userRouter,quizRouter} from './router'
const app = express();

app.use('/user',userRouter)
app.use('/quiz',quizRouter)

// in router (라우터 + 라우트들까지)

import {profile,quiz} from './controller'

const userRouter = express.Router('/user')
const quizRouter = express.Router('/quiz')

userRouter.get('/:id',profile);
quizRouter.get('/:id',quiz);

// in controller

export function profile(req,res){
	return res.send('user => profile')
}
export function quiz(req,res){
	return res.send('quiz => getQuiz')
}

2-3 라우트를 할때 controller함수의 '주체'를 생각하자.

만약 메인페이지에서 user의 프로필을 보여준다고 생각하자.

폴더의 분기때문에 그런건데 위의 상황에서 라우트는 app.get('/',showProfile) 일 거니까 user 라우터 폴더안에 있지는 않겠지만. '유저'의 프로필을 보여주는거기때문에 user 컨트롤러 폴더안에는 있을거다.

  • /user의 라우터가 아니기때문에 user라우터 폴더에는 x
  • user의 프로필을 보여주는거기 때문에 user컨트롤러 폴더에는 o

3. url params + 순서

Url안에서 변수를 추가하는 느낌

// in userRouter.js

const userRouter = express.Router('/user')

=> /user 라우터 안에서 라우팅을 하니까 /user/:id 이런식으로 path를 안해도 되겄지?
userRouter.get('/edit',edit);
userRouter.get('/:id',profile);
// in userController.js

function profile(req,res){
	const {id} = req.params //  ex) localhost:port/user/123 => id=123
}

3.1 순서가 바뀐다면..?

userRouter.get('/:id',profile);
userRouter.get('/edit',edit);

어떨까? /user/edit이라는 경로에 들어갔지만 edit컨트롤러가 실행되지는 않을거다.
익스프레스 입장에서는 /:id나 /edit이나 똑같다. params에 id가 edit이라고 인식하는거다.
=> 그러니까 순서를 잘 생각하자.

3.2 path에 정규식도 쓸수있다.

userRouter.get('/:id(\\d+)',profile);

어지러울수 있는데 :id는 무시하자 어차피 placeholder같은 느낌이니까. 정규식을 뜯자면

  • () : 정규식의 그룹
  • \d+ : \d:숫자 +: 선행이 (1)개 이상 연속 = 숫자가 1개이상 연속
  • 이스케이프 규칙 준수! ( 역슬래쉬()가 2번! \\d )

즉 id 파라미터가 숫자로만 request가 들어올때 profile컨트롤러 함수를 실행해서 response를 리턴하겠다는 소리다.

=>

  • 숫자가아닌 string이면 애초에 정규식을 통과하지 못하니 해당 라우트가 없는거나 다름없고,
  • 라우트가 없으니 cannot get / 이 뜰거다.
  • 통과하려면 userRouter,get('/:id(\w+)',handler)이런 라우트가 뚫려있어야 통과를 할거다

4. 외부 미들웨어 (external middleware)

4.1 Morgan

npm install morgan

내가 설정한대로 미들웨어를 반환해주는 패키지고. 아직은 큰 사용이 없어서 나중에 사용시 추가하려고 한다

import morgan from 'morgan'

app.use(morgan('dev'));

앞으로 모든컨트롤러 함수는 morgan('dev') 미들웨어를 거칠거고.
서버 콘솔을보니까 http 메서드, 속도, statuscode등 정보를 console.log해준다. morgan덕인듯!

profile
작은 나의 개발 일기장

0개의 댓글