본문 바로가기
학원에서 배운 것/node.js

KDT 5th 웹개발 입문 수업 24일차

by 쿠리의일상 2023. 3. 9.

express Routing

프론트에서 백엔드로 요청을 보낼 때는 주소값을 다르게 보내서 요청한다.

따라서 백엔드에서는 각각 주소에 따라서 각기 다른 역할을 해주면 된다.

➡️ 주소에 따라서 각기 다른 역할을 하도록 나누는 방법Rounting 이라고 한다.

 

  1. 메서드별 요청에 따른 Routing
    1. app.post()
    2. app.get()
    3. app.put()
    4. app.delete()
  2. Express router 미들웨어 -> express.Router()

express.Router() 를 사용하면 특정 url 요청에 대한 것들을 묶어서 처리가 가능

해당 라우터, 미들웨어 사용을 위해 app.use(사용해줄주소, 라우터명) 으로 설정해준다.

라우터를 설정해주면 해당 라우터명을 사용하여 서버 설정이 가능

const express = require('express');
const app = express();
const userRouter = express.Router();
const PORT = 4000;

app.use('/user', userRouter);

// http://localhost:4000/users 가 됨
userRouter.get('/', (req, res) => {
  res.send('회원 목록');
});

userRouter.get('/id/:id', (req, res) => {
  res.send('특정 회원 목록');
});

userRouter.post('/add', (req, res) => {
  res.send('회원 등록');
});

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

app.listen(PORT, () => {});

 

* localhost 는 127.0.0.1 로 대체가 가능!

즉, http://localhost:4000 는 http://127.0.0.1:4000 과 동일.

  • 위 userRouter는 http://localhost:4000/user 를 뜻하게 되고 
  • http://localhost:4000/user/ --> 회원 목록
  • http://localhost:4000/user/id/아이디 --> 특정 회원 목록
  • http://localhost:4000/user/add --> 회원 등록

 

 

 

회원 관련 API 만들기

const express = require('express');

const app = express();
const userRouter = express.Router();
const userModify = express.Router();
const userDelete = express.Router();

const PORT = 4000;

//TEMP DATA
const USER = {
  1: {
    id: 'test',
    name: '홍길동',
  },
};

app.use('/users', userRouter);

// 초기
app.get('/', (req, res) => {
  res.send('Express World');
});

// 회원 목록
userRouter.get('/', (req, res) => {
  res.send(USER);
});

// 회원 추가
userRouter.post('/add', (req, res) => {
  if (!req.query.id || !req.query.name) return res.send('쿼리 입력 오류');

  const newUser = {
    id: req.query.id,
    name: req.query.name,
  };
  USER[Object.keys(USER).length + 1] = newUser;

  res.send('회원 등록 완료');
});

// 회원 수정
userRouter.use('/modify', userModify);
userModify.put('/:uid', (req, res) => {
  if (!req.params.uid || !req.query.id || !req.query.name)
    return res.send('쿼리 입력 오류');

  if (req.params.uid in USER) {
    // USER[req.params.uid].id = req.query.id;
    // USER[req.params.uid].name = req.query.name;
    USER[req.params.uid] = {
      id: req.query.id,
      name: req.query.name,
    };
    res.send('회원 수정 완료');
  } else {
    res.send('쿼리 입력 오류');
  }
});

// 회원 삭제
userRouter.use('/delete', userDelete);
userDelete.delete('/:uid', (req, res) => {
  if (!req.params.uid) return res.send('쿼리 입력 오류');

  delete USER[req.params.uid];
  res.send('회원 삭제 완료');
});

// 서버 오픈
app.listen(PORT, () => {});

간단하게 객체형식으로 받아와서 처리

서버를 재시작하면 객체 정보가 리셋되어 버리므로 해당 정보는 따로 DB처리 해줘야 한다.

 

 

서버에서 받은 데이터로 프론트에서 그리기

res.write() 로 하나씩 그려줄 수 있다.

res.writeHead() 로는 <head> 태그에 들어가는 정보를 설정할 수 있다.

userRouter.get('/show', (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/html; charset=UTF-8' });
  res.write('<h1>Hello Dynamic Web PAge</h1>');

  for (let i = 0; i < USER_ARR.length; i += 1) {
    res.write(`<h2>USER ID is ${USER_ARR[i].id}</h2>`);
    res.write(`<h2>USER NAME is ${USER_ARR[i].name}</h2>`);
  }
  res.end();
});

---> 불편하므로 거의 사용하지 않음

대신 View Engine 사용 -> SSR 이 기본!

1. ejs : 가장 기본이 되는 View Engine, HTML 문법 사용 / 레이아웃 기능 X

2. pug(jade) : HTML 문법을 단순화 / 레이아웃 기능 O

3. Nunjucks : HTML 문법 그대로 사용 / 레이아웃 기능 O

 

 

ejs

npm i -D ejs 로 설치

 

express에게 어떤 View Engine으로 웹페이지를 그릴 것인지 알려줘야 한다.

app.set('view engine', 'ejs');

동적 웹페이지는 views 폴더에서 관리(직접 만들어줘야 하며)

파일 확장자는 .ejs 로 작성하기

userRouter.get('/ejs', (req, res) => {
  res.render('index.ejs', { USER_ARR, userCounts: USER_ARR.length });
});

get() 메서드로 res.render(파일명, 전달하고픈 데이터) 함수로 파일명을 입력해주면 파일 내용대로 그려진다.

데이터는 객체 형태로 전달이 됨.

 

위처럼 오브젝트로 전달된 데이터는 ejs 파일 내부에서 <%= %> 문법을 사용하여 res.render()에 넣어줬던 데이터의 오브젝트 필드명으로 바로 호출이 가능하다.

즉, 데이터를 받을 때에는 <%= %> 문법을 사용함!

<h1>회원 목록</h1>
  <h2>
    총 회원 수 : <%= userCounts %> 명
  </h2>
  <ul>
    <li>
      <p>
        ID : <%= USER_ARR[0].id %>
      </p>
      <p>
        NAME : <%= USER_ARR[0].name %>
      </p>
    </li>
  </ul>

신기하당

 

 

ejs if, for 문 사용하기

<h1>회원 목록</h1>
  <h2>
    총 회원 수 : <%= userCounts %> 명
  </h2>
  <ul>
    <% if(userCounts > 0) { %>
      <%for(let i = 0; i< userCounts; i++) { %>
        <li>
          <p>
            ID : <%= USER_ARR[i].id %>
          </p>
          <p>
            NAME : <%= USER_ARR[i].name %>
          </p>
        </li>
      <% } %>
    <% } else { %>
      <li>회원 정보가 없습니다.</li>
    <% } %>
  </ul>

JS 문법을 HTML 코드에 적용하고자 한다면, <% %> 안에 코드를 사용하면 된다.

 

 

ejs 확장 프로그램-----

 

index.ejs 파일에 css를 적용하기

views 폴더에 css 폴더를 만들고 style.css 파일을 만들어준다.

아는 정보로 <link> 로 css를 연동해주려고 해도 되지 않는다. 이는 해킹 방지의 일환으로

static 미들웨어를 사용해준다.

static

브라우저(프론트엔드)에서 접근이 가능한 폴더 위치를 백엔드상에서 지정해주는 것!

app.use(express.static('폴더위치')) 형태로 사용

해당 미들웨어를 사용하면 프로젝트에서 사용하는 폴더 경로의 시작점이 지정되는 것이므로

app.use(express.static('views'));
app.use(express.static('js'));

위 코드에 의해 폴더 경로의 시작점은 localhost:4000/views/ 와 동일한 위치를 가리키게되는 것이다.

static으로 폴더 위치를 지정해주면 여러 폴더를 각각 알아서 찾아간다. (파일이 없으면 에러 발생)

 

절대 경로 : __dirname

현재 파일이 위치하는 절대 경로, node.js에서 제공해주는 프로퍼티이다.

app.use(express.static(__dirname + '/views'));
app.use(express.static(__dirname + '/js'));

위의 폴더위치를 좀더 정확하게 지정해줄 수 있다.

 

// app.use(express.static(__dirname + '/views'));
app.use('/css', express.static(__dirname + '/views/css'));

// app.use(express.static(__dirname + '/js'));
app.use('/js', express.static(__dirname + '/js'));

추가로, 매개변수 2개를 사용할 때, 첫번째 매개변수에 프론트엔트에서 요청되는 경로에 따라 폴더를 따로 지정해줄 수 있다.

 

 

express.static() 주의 사항

브라우저에서 접근이 가능한 기본 폴더를 설정하는 만큼 너무 많은 폴더를 정하는 것은 지양하는 게 좋다.

보통은 Public 이라는 폴더를 기본으로 설정해놓고 해당 폴더만 설정하고, 클라이언트가 접근이 가능한 폴더로써 css, js, 이미지 등을 위치시켜준다.

 

 

Express 기본 폴더 구조

 

 

public 폴더로 관리

public 폴더 안에 css, js, image 폴더를 만들어서 관리해준다.

app.use(express.static(__dirname + '/public'));

 

 

기능을 파일로 분리하기

각각의 기능을 파일로 나눈 뒤, 모듈 타입으로 라우팅 처리를 해준다.

 

모듈 빼기

module.exports = router;

하나의 모듈로서 불러오기 위해서 선언

 

사용하고자 하는 js 파일에서 require() 로 해당 모듈을 불러올 수 있고

const userRouter = require('./routes/users');

메인 서버 부분에는 위처럼 user와 관련된 모듈을 불러와서 사용해준다.