Node로 라우팅하기

Choi Rim·2021년 9월 25일
0

Node & Express

목록 보기
3/3
post-thumbnail

Node로 라우팅을 해보자! 🏄🏻‍♀️

라우팅 (routing)

  • 클라이언트가 요청한 콘텐츠를 전송하는 메커니즘
  • 웹 기반 클라이언트/서버 애플리케이션에서 클라이언트는 원하는 콘텐츠를 URL, 즉 경로(path)와 쿼리스트링(querystring)으로 요청한다.

라우팅 적용하기

이전 글 <Node로 기본적인 웹 서버 만들기> 에서 만든 기본적인 웹 서버를 더 발전시켜보자!

  • 홈페이지, 어바웃 페이지, 404 페이지로 구성된 최소한의 웹 사이트를 전송해보자
// helloworld.js
const http = require('http');
const port = process.env.PORT || 3000;

const server = http.createServer((req, res) => {
    // 쿼리스트링, 옵션인 마지막 슬래시를 없애고 소문자로 바꿔서 url을 정규화한다.
    const path = req.url.replace(/\/?(?:\?.*)?$/, '').toLowerCase()
    switch(path) {
        case '':
            res.writeHead(200, { 'Content-Type': 'text/plain' })
            res.end('Homepage')
            break
        case '/about':
            res.writeHead(200, { 'Content-Type': 'text/plain' })
            res.end('About')
            break
        default:
            res.writeHead(200, { 'Content-Type': 'text/plain' })
            res.end('Not Found')
            break
    }
})

server.listen(port, () => console.log(`server started on port ${port}; press Ctrl-C to terminate....`))

정적 자원 전송

  • 라우팅에 성공했으니 실제 HTML과 로고 이미지를 전송해보자
    • HTML와 로고 이미지 같은 파일을 정적(static) 자원이라 부르는 이유는 일반적으로 바뀌지 않기 때문이다.
  • 노드에서는 파일을 열고, 콘텐츠를 읽어서 브라우저에 보내야 한다.
    • 이를 위해 정적 파일을 보관할 public 디렉터리를 만들어야 한다.

  • public 디렉터리에 home.html, about.html, 404.html 파일을 만든다
  • img 서브 디렉터리를 만들어 img/logo.png 파일을 저장한다.
  • html 파일에 <img src="/img/logo.png alt="logo">와 같이 로고 파일을 링크한다.
  • html 파일을 작성한다.
// helloworld.js
const http = require('http');
const fs = require('fs')
const port = process.env.PORT || 3000;

function serveStaticFile(res, path, contentType, responseCode = 200) {
    fs.readFile(__dirname + path, (err, data) => {
        if(err) {
            res.writeHead(500, { 'Content-Type': 'text/plain' })
            return res.end('500 - Internal Error')
        }
        res.writeHead(responseCode, { 'Content-Type': contentType })
        res.end(data)
    })
}

const server = http.createServer((req, res) => {
    // 쿼리스트링, 옵션인 마지막 슬래시를 없애고 소문자로 바꿔서 url을 정규화한다.
    const path = req.url.replace(/\/?(?:\?.*)?$/, '').toLowerCase()
    switch(path) {
        case '':
            serveStaticFile(res, '/public/home.html', 'text/html')
            break
        case '/about':
            serveStaticFile(res, '/public/about.html', 'text/html')
            break
        case '/img/image.png':
            serveStaticFile(res, '/public/img/image.png', 'image/png')
            break
        default:
            serveStaticFile(res, '/public/404.html', 'text/html', 404)
            break
    }
})

server.listen(port, () => console.log(`server started on port ${port}; press Ctrl-C to terminate....`))
  • helloworld.js 파일을 위와 같이 수정한다.
const fs = require('fs')
  • 파일 로드는 'fs'라는 객체로 사용할 수 있다. require 함수에서 'fs'를 읽고, 그 안에 있는 메소드를 호출하여 로드한다.
fs.readFile(파일의 경로, 인코딩, 콜백함수)
  • fs.readFile은 파일을 비동기적으로 읽는 메서드이다.
  • fs.readFiled은 콜백이라고 부르는 패턴을 사용한다.
    • 파일을 호출할 때 콜백 함수를 전달하면, 함수가 실행을 마쳤을 때 콜백 함수가 호출된다.
    • 위 예제에서는 fs.readFile이 지정한 파일의 콘텐츠를 읽고, 다 읽은 다음에는 콜백 함수를 실행한다.
      • 만약 파일이 존재하지 않거나 권한 문제 때문에 파일을 읽을 수 없다면 err 변수가 만들어지고 함수는 서버 오류를 나타내는 HTTP 상태 코드 500을 반환한다.
      • 파일을 성공적으로 읽었으면 콜백 함수에 전달된 응답 코드와 콘텐츠 타입과 함게 파일을 클라이언트에 전송한다.
    • __dirname은 현재 실행 중인 스크립트가 존재하는 디렉터리이다.
      • 스크립트가 /home/sites/app.js에 존재한다면 __dirname은 /home/sites다.
      • __dirname 변수는 가능한 자주 활용하는 편이 좋다.
      • 이 변수를 활용하지 않으면, 앱을 다른 디렉터리에서 실행했을 때 찾기 힘든 오류가 일어날 수 있다.

<참고>

profile
https://rimi0108.github.io/

0개의 댓글