2023.12.06(수)

🚝Express

  • 설치 : npm i express

  • Simple usage

    const express = require('express')
    const app = express()
    
    app.get('/', function (req, res) {
       res.send('Hello World')
    })
    
    app.listen(3000)

🚩기본 사용법

Basic Routing

  • 기본 형태

    app.METHOD(PATH, HANDLER)
  • app : express instance

  • METHOD : 소문자 HTTP request method (get, post, put, patch, delete, head, connect, options, trace)

  • PATH : server path → 변수 및 정규 표현식 사용 가능

    • express는 route path를 매칭하기 위해 path-to-regexp 사용 (Express Route Tester)
    • route parameter를 이용하면 req.params에 key-value 형태로 mapping됨 (value는 String 형태로 저장됨에 주의)
      • 기본 형태 : :param_name
        • ※ paramname은 반드시 문자`[A-Za-z0-9]`로 구성되어야 함
          app.get('/users/**:userId**/books/**:bookId**', (req, res) => {
            res.send(req.params)
          })
          Request URL: http://localhost:3000/users/**34**/books/**8989**
          req.params: { "userId": "34", "bookId": "8989" }
        • hyphen(-)과 dot(.)은 문자 그대로 해석되므로 목적에 맞게 사용 가능
          Route path: /flights/**:from-:to**
          Request URL: http://localhost:3000/flights/LAX-SFO
          req.params: { "from": "LAX", "to": "SFO" }
          Route path: /plantae/**:genus.:species**
          Request URL: http://localhost:3000/plantae/Prunus.persica
          req.params: { "genus": "Prunus", "species": "persica" }
      • 괄호를 이용해서 정규 표현식과 함께 : :param_name(regex)
        • ※ 정규 표현식도 문자열의 일부이기 때문에 백슬래시(\)에 escape 문자를 사용해야함 (\d+\\d+)
          Route path: /user/**:userId(\\d+)**
          Request URL: http://localhost:3000/user/42
          req.params: {"userId": "42"}
  • HANDLER : route가 매칭되었을 때 실행될 function

    • 기본적으로 handler function은 requestresponse 객체를 parameter로 받음

    • 추가적으로 next() 객체를 이용해 단계적으로 처리 가능

      • HANDLER 인자로 함수 형태를 사용 (next 객체를 반드시 명시)
        app.get('/example/b', (req, res, **next**) => {
          console.log('the response will be sent by the next function ...')
          **next()**
        }, (req, res) => {
          res.send('Hello from B!')
        })
      • HANDLER 인자로 함수 array 사용
        const cb0 = function (req, res, **next**) {
          console.log('CB0')
          **next()**
        }
        
        const cb1 = function (req, res, **next**) {
          console.log('CB1')
          **next()**
        }
        
        const cb2 = function (req, res) {
          res.send('Hello from C!')
        }
        
        app.get('/example/c', [cb0, cb1, cb2])
      • 함수 형태로 전달 & 함수 array 둘 다 사용
        const cb0 = function (req, res, **next**) {
          console.log('CB0')
          **next()**
        }
        
        const cb1 = function (req, res, **next**) {
          console.log('CB1')
          **next()**
        }
        
        app.get('/example/d', [cb0, cb1], (req, res, **next**) => {
          console.log('the response will be sent by the next function ...')
          **next()**
        }, (req, res) => {
          res.send('Hello from D!')
        })
    • Chainable route handler : app.route()🔗

      • 같은 PATH에 대해 METHOD는 상이할 수 있는데 이 경우 중복과 오타를 줄이기 위해 chainable route handler 사용 가능

      • 활용 예시

        • 하나의 PATH에서 get, post, put 세가지 METHOD에 대한 요청을 처리할 수 있음

          app.route('/book')
            .get((req, res) => {
              res.send('Get a random book')
            })
            .post((req, res) => {
              res.send('Add a book')
            })
            .put((req, res) => {
              res.send('Update the book')
            })
    • Modular, Mountable route handler : express.Router🔗

      • router를 분리하여 관리하고 싶다면 module로 만들 수 있음

      • 활용 예시

        • birds.js라는 router file을 따로 생성

          const express = require('express')
          const router = express.Router()
          
          // middleware that is specific to this router (invoked for any requests passed to this router)
          router.use((req, res, next) => {
            console.log('Time: ', Date.now())
            next()
          })
          // define the home page route
          router.get('/', (req, res) => {
            res.send('Birds home page')
          })
          // define the about route
          router.get('/about', (req, res) => {
            res.send('About birds')
          })
          
          module.exports = router
        • app에 router module을 load해서 사용

          const router = require('./birds')
          
          // ...
          // only requests to /birds/* will be sent to our "router"
          app.use('/birds', router)

Response Methods

MethodDescription
res.download()Prompt a file to be downloaded.
res.end()End the response process.
res.json()Send a JSON response.
res.jsonp()Send a JSON response with JSONP support.
res.redirect()Redirect a request.
res.render()Render a view template.
res.send()Send a response of various types.
res.sendFile()Send a file as an octet stream.
res.sendStatus()Set the response status code and send its string representation as the response body.
  • JSON(JavaScript Object Notation)
    • 객체(Object) : 데이터를 하나씩 ❌ → 모아서 한 덩어리
    • 자바스크립트 객체 : 이름(name)과 값(value)으로 구성된 프로퍼티(property)의 정렬되지 않은 집합
    • 자바스크립트의 객체를 문자열로 표현하는 방법
    • JSON.stringify(object) : 인자로 받은 객체를 JSON 문자열로 반환 (JavaScript Object → JSON 데이터)
    • JSON.parse(string) : 인자로 받은 문자열을 Javascript Object로 변경해 반환 (JSON 데이터 → JavaScript Object)
    • undefined, function은 변환되지 않음에 주의!
  • express의 res.json() method
    • 내부적으로 JSON.stringify()를 사용하여 object parameter를 JSON 문자열로 반환하여 응답을 보냄
    • 매개변수는 객체, 배열, 문자열, 부울, 숫자 또는 null을 포함한 모든 JSON 유형일 수 있으며, 이를 사용하여 다른 값을 JSON으로 변환 가능
      res.json(null)
      res.json({ user: 'tobi' })
      res.status(500).json({ error: 'message' })

      💡 물론 그냥 res.send()를 이용하면 express가 parameter의 type에 따라 적합한 Content-Type으로 지정하여 응답을 보내주긴 하지만 type에 맞는 method를 명시적으로 사용하는 것이 더 바람직하다.
      ex) res.send()로 Array나 Object를 보내면 express가 JSON 형식으로 응답을 보냄

Serving static files in Express

  • 정적 파일(static file) = HTML 파일, CSS 파일, JavaScript 파일, 이미지 파일 등
  • 기본 형태
    express.static(root, [options])
    • root : 정적 자산들(static assets)이 들어있는 root directory
    • root directory public
      app.use(express.static('public'))
      http://localhost:3000/images/kitten.jpg
      http://localhost:3000/css/style.css
      http://localhost:3000/js/app.js
      http://localhost:3000/images/bg.png
      http://localhost:3000/hello.html
      • express는 static directory의 상대 경로로 파일들을 찾기 때문에 URL에 directory는 포함❌
      • 여러 개의 directory를 사용하려면 함수를 여러 번 호출하면 됨 (이 경우 express는 호출 순서대로 해당 directory에서 파일을 찾음)
        // public -> files의 순서로 look up
        app.use(express.static('public'))
        app.use(express.static('files'))
    • 실제 파일 시스템에 없는 virtual path prefix /static과 함께
      app.use('/static', express.static('public'))
      http://localhost:3000**/static**/images/kitten.jpg
      http://localhost:3000**/static**/css/style.css
      http://localhost:3000**/static**/js/app.js
      http://localhost:3000**/static**/images/bg.png
      http://localhost:3000**/static**/hello.html
    • root path를 absolute path
      const path = require('path')
      app.use('/static', express.static(path.join(__dirname, 'public')))

http 모듈을 사용하다가 express 모듈을 사용해보니 정말 편한 것 같다.😀

profile
이것저것 관심 많은 개발자👩‍💻

0개의 댓글