생활코딩

Coding Everybody

라우터

토픽 생활코딩 > WEB > WEB2 - Node.js > Node.js - Express

수업소개

관리하는 페이지가 많아짐에 따라서 코드의 복잡도가 급격히 높아지게 됩니다. 복잡도를 낮추는 방법이 라우터입니다. 라우터를 알아봅시다.

 

 

 

강의1

라우터를 살펴보기 전에 기존 앱의 주소체계를 변경하는 작업을 합시다. 

 

 

 

소스코드

변경사항

main.js

var express = require('express')
var app = express()
var fs = require('fs');
var path = require('path');
var qs = require('querystring');
var bodyParser = require('body-parser');
var sanitizeHtml = require('sanitize-html');
var compression = require('compression')
var template = require('./lib/template.js');

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compression());
app.get('*', function(request, response, next){
  fs.readdir('./data', function(error, filelist){
    request.list = filelist;
    next();
  });
});



//route, routing
//app.get('/', (req, res) => res.send('Hello World!'))
app.get('/', function(request, response) { 
  var title = 'Welcome';
  var description = 'Hello, Node.js';
  var list = template.list(request.list);
  var html = template.HTML(title, list,
    `
    <h2>${title}</h2>${description}
    <img src="/images/hello.jpg" style="width:300px; display:block; margin-top:10px;">
    `,
    `<a href="/topic/create">create</a>`
  ); 
  response.send(html);
});

app.get('/topic/create', function(request, response){
  var title = 'WEB - create';
  var list = template.list(request.list);
  var html = template.HTML(title, list, `
    <form action="/topic/create_process" method="post">
      <p><input type="text" name="title" placeholder="title"></p>
      <p>
        <textarea name="description" placeholder="description"></textarea>
      </p>
      <p>
        <input type="submit">
      </p>
    </form>
  `, '');
  response.send(html);
});

app.post('/topic/create_process', function(request, response){
  var post = request.body;
  var title = post.title;
  var description = post.description;
  fs.writeFile(`data/${title}`, description, 'utf8', function(err){
    response.redirect(`/topic/${title}`);
  });
});

app.get('/topic/update/:pageId', function(request, response){
  var filteredId = path.parse(request.params.pageId).base;
  fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
    var title = request.params.pageId;
    var list = template.list(request.list);
    var html = template.HTML(title, list,
      `
      <form action="/topic/update_process" method="post">
        <input type="hidden" name="id" value="${title}">
        <p><input type="text" name="title" placeholder="title" value="${title}"></p>
        <p>
          <textarea name="description" placeholder="description">${description}</textarea>
        </p>
        <p>
          <input type="submit">
        </p>
      </form>
      `,
      `<a href="/topic/create">create</a> <a href="/topic/update/${title}">update</a>`
    );
    response.send(html);
  });
});

app.post('/topic/update_process', function(request, response){
  var post = request.body;
  var id = post.id;
  var title = post.title;
  var description = post.description;
  fs.rename(`data/${id}`, `data/${title}`, function(error){
    fs.writeFile(`data/${title}`, description, 'utf8', function(err){
      response.redirect(`/topic/${title}`);
    })
  });
});

app.post('/topic/delete_process', function(request, response){
  var post = request.body;
  var id = post.id;
  var filteredId = path.parse(id).base;
  fs.unlink(`data/${filteredId}`, function(error){
    response.redirect('/');
  });
});

app.get('/topic/:pageId', function(request, response, next) { 
  var filteredId = path.parse(request.params.pageId).base;
  fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
    if(err){
      next(err);
    } else {
      var title = request.params.pageId;
      var sanitizedTitle = sanitizeHtml(title);
      var sanitizedDescription = sanitizeHtml(description, {
        allowedTags:['h1']
      });
      var list = template.list(request.list);
      var html = template.HTML(sanitizedTitle, list,
        `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
        ` <a href="/topic/create">create</a>
          <a href="/topic/update/${sanitizedTitle}">update</a>
          <form action="/topic/delete_process" method="post">
            <input type="hidden" name="id" value="${sanitizedTitle}">
            <input type="submit" value="delete">
          </form>`
      );
      response.send(html);
    }
  });
});








app.use(function(req, res, next) {
  res.status(404).send('Sorry cant find that!');
});

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
});

app.listen(3000, function() {
  console.log('Example app listening on port 3000!')
});

 

template.js

module.exports = {
  HTML:function(title, list, body, control){
    return `
    <!doctype html>
    <html>
    <head>
      <title>WEB1 - ${title}</title>
      <meta charset="utf-8">
    </head>
    <body>
      <h1><a href="/">WEB</a></h1>
      ${list}
      ${control}
      ${body}
    </body>
    </html>
    `;
  },list:function(filelist){
    var list = '<ul>';
    var i = 0;
    while(i < filelist.length){
      list = list + `<li><a href="/topic/${filelist[i]}">${filelist[i]}</a></li>`;
      i = i + 1;
    }
    list = list+'</ul>';
    return list;
  }
}

 

 

 

강의2

라우터를 만들어서 파일로 분리

 

 

 

소스코드 

변경사항

main.js

var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var qs = require('querystring');
var bodyParser = require('body-parser');
var sanitizeHtml = require('sanitize-html');
var compression = require('compression')
var template = require('./lib/template.js');
var topicRouter = require('./routes/topic');

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compression());
app.get('*', function(request, response, next){
  fs.readdir('./data', function(error, filelist){
    request.list = filelist;
    next();
  });
});

app.use('/topic', topicRouter);


//route, routing
//app.get('/', (req, res) => res.send('Hello World!'))
app.get('/', function(request, response) { 
  var title = 'Welcome';
  var description = 'Hello, Node.js';
  var list = template.list(request.list);
  var html = template.HTML(title, list,
    `
    <h2>${title}</h2>${description}
    <img src="/images/hello.jpg" style="width:300px; display:block; margin-top:10px;">
    `,
    `<a href="/topic/create">create</a>`
  ); 
  response.send(html);
});


 

topic.js

var express = require('express');
var router = express.Router();
var path = require('path');
var fs = require('fs');
var sanitizeHtml = require('sanitize-html');
var template = require('../lib/template.js');

router.get('/create', function(request, response){
    var title = 'WEB - create';
    var list = template.list(request.list);
    var html = template.HTML(title, list, `
      <form action="/topic/create_process" method="post">
        <p><input type="text" name="title" placeholder="title"></p>
        <p>
          <textarea name="description" placeholder="description"></textarea>
        </p>
        <p>
          <input type="submit">
        </p>
      </form>
    `, '');
    response.send(html);
  });
  
  router.post('/create_process', function(request, response){
    var post = request.body;
    var title = post.title;
    var description = post.description;
    fs.writeFile(`data/${title}`, description, 'utf8', function(err){
      response.redirect(`/topic/${title}`);
    });
  });
  
  router.get('/update/:pageId', function(request, response){
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
      var title = request.params.pageId;
      var list = template.list(request.list);
      var html = template.HTML(title, list,
        `
        <form action="/topic/update_process" method="post">
          <input type="hidden" name="id" value="${title}">
          <p><input type="text" name="title" placeholder="title" value="${title}"></p>
          <p>
            <textarea name="description" placeholder="description">${description}</textarea>
          </p>
          <p>
            <input type="submit">
          </p>
        </form>
        `,
        `<a href="/topic/create">create</a> <a href="/topic/update/${title}">update</a>`
      );
      response.send(html);
    });
  });
  
  router.post('/update_process', function(request, response){
    var post = request.body;
    var id = post.id;
    var title = post.title;
    var description = post.description;
    fs.rename(`data/${id}`, `data/${title}`, function(error){
      fs.writeFile(`data/${title}`, description, 'utf8', function(err){
        response.redirect(`/topic/${title}`);
      })
    });
  });
  
  router.post('/delete_process', function(request, response){
    var post = request.body;
    var id = post.id;
    var filteredId = path.parse(id).base;
    fs.unlink(`data/${filteredId}`, function(error){
      response.redirect('/');
    });
  });
  
  router.get('/:pageId', function(request, response, next) { 
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf8', function(err, description){
      if(err){
        next(err);
      } else {
        var title = request.params.pageId;
        var sanitizedTitle = sanitizeHtml(title);
        var sanitizedDescription = sanitizeHtml(description, {
          allowedTags:['h1']
        });
        var list = template.list(request.list);
        var html = template.HTML(sanitizedTitle, list,
          `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
          ` <a href="/topic/create">create</a>
            <a href="/topic/update/${sanitizedTitle}">update</a>
            <form action="/topic/delete_process" method="post">
              <input type="hidden" name="id" value="${sanitizedTitle}">
              <input type="submit" value="delete">
            </form>`
        );
        response.send(html);
      }
    });
  });
  module.exports = router;

 

 

 

강의3

홈페이지를 파일로 분리해봅시다.

 

 

 

소스코드

변경사항

main.js

var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
var compression = require('compression')

var indexRouter = require('./routes/index');
var topicRouter = require('./routes/topic');

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compression());
app.get('*', function(request, response, next){
  fs.readdir('./data', function(error, filelist){
    request.list = filelist;
    next();
  });
});

app.use('/', indexRouter);
app.use('/topic', topicRouter);

app.use(function(req, res, next) {
  res.status(404).send('Sorry cant find that!');
});

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
});

app.listen(3000, function() {
  console.log('Example app listening on port 3000!')
});

 

routes/index.js

var express = require('express');
var router = express.Router();
var template = require('../lib/template.js');

router.get('/', function(request, response) { 
    var title = 'Welcome';
    var description = 'Hello, Node.js';
    var list = template.list(request.list);
    var html = template.HTML(title, list,
      `
      <h2>${title}</h2>${description}
      <img src="/images/hello.jpg" style="width:300px; display:block; margin-top:10px;">
      `,
      `<a href="/topic/create">create</a>`
    ); 
    response.send(html);
  });
  
  module.exports = router;

 

댓글

댓글 본문
  1. 감자
    22.12.22
  2. 당당
    2022.11.19
  3. kimkk
    request에 있는 originalUrl 속성을 쓰면 됩니다.

    router.get('/create', (request, response) => {

    var fullUrl = request.protocol + '://' + request.get('host')
    + request.originalUrl;

    console.log(`fullUrl:${fullUrl}`);

    출처: https://stackoverflow.com......ejs
    대화보기
    • kimkk
      topic.js 에서는 /topic을 기준으로한 상대 경로를 지정해주어야 합니다.
      즉 /topic/foo 라면 topic.js 에서는 /foo라고 지정해주면 됩니다.
      대화보기
      • 케굴
        2022-01-03
      • jeisyoon
        2021.03.17 Express Router - OK
      • 모듈과 비슷하게 라우터는 활용시 (도메인별)정리가 가능
      • hanel_
        21.2.25
      • 김지호
        21 01 08
      • 생활둘기
        2021 1 4
      • 콜라
        20201029 완료
      • Yong Hyun Lee
        완료 201003
      • 퍼스니
        app.use('/topic', 라우터모듈); 일때, localhost/topic/update 라고 예시를 들면 /topic이 처리된 상태로 그 뒤에 남은 /update가 router 모듈안에서 대응하는 미들웨어에 동작함니다
        대화보기
        • 전주호
          완료
        • ldhan0715
          20-09-15
        • 뚜루뚜루뚭
          감사합니다
        • 쑤우
          수강완료. 감사합니다~
        • 성우
          안녕하세요.ㅎㅎ
          강의 2에서 topic.js안에 /topic/~~(미들웨어 함수가 적용되는 경로) 에서 /topic은 지워야된다고 하시는거 같은데 영상을 돌려봐도 잘 이해가 안 가요ㅜㅜㅜ
          왜 지워야하는지 조금더 쉽게 설명해주실 수 있나요?
        • ㄱㅎㅈ
          'create' 라는 title을 이용할 수 없게 사전에 js 코드로 막아주는게 좋을 거 같네요.
          대화보기
          • 고고고고고곡
            강의1에서 create_process처럼 post로 받는 라우터들은 위로 올릴 필요가 없습니다.
          • river9028
            create 등을 예약어처럼 사용한다고 하셨는데 이럴 경우 "title이 "create"인 문서를 작성하면 문서와 링크는 생기나 문서로 이동이 안되고 예약어 페이지(새 문서 작성 페이지)로 이동합니다. 이런 경우는 어떻게 방지해야 할까요?
          • 파이어뱃
            Express generator가 생성한 backend가
            이번 라우팅 지식이 없으면 힘든 것 같아요 ㅎ 감사합니다.

            const express = require('express')
            const app = express();
            VS
            const express = require('express')
            const router = express.router();

            이렇게 하는 이유 : 라우팅에 따라 같은 상위 경로에 속하는 라우팅들을 파일로 분리하기 위해서
          • 강다리
            완료
          • 굼벵이
            완료
          • 미고밈
            @_@
          • jo_onc
            굳!
          • 삼고잉
            잘 읽었습니다
          • 연수아빠
            편리한 기능입니다..
          • main.js에서 router에서 받아들이 path를 설정하고, routes 폴더 아래에 있는 router들 안에 있는 html contents들은 path가 hard coding되어 있는데요.
            이렇게 되면, path를 수정하고 싶을 때, main.js에서 수정하고, 그에 따라서 hard code된 path를 다 하나하나 수정해야 할 것 같습니다. router에서 현재 처리하고 있는 path가 무엇인지 받아오는 변수는 없나요?