๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒŒ | WEB DEV/NodeJS

[NodeJS+Express] 11. URLํŒŒ๋ผ๋ฏธํ„ฐ (์ƒ์„ธํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ)

by KASSID 2023. 10. 15.

๋ชฉ์ฐจ

    728x90

    ์ด๋ฒˆ์—๋Š” URL ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌธ๋ฒ•์„ ์ด์šฉํ•ด ์ƒ์„ธํŽ˜์ด์ง€๋ฅผ ์ œ์ž‘ํ•ด๋ณด์ž.

     

    0. ์ƒ์„ธํŽ˜์ด์ง€ ํ˜•ํƒœ

    ์ง€๊ธˆ๊นŒ์ง€๋Š” ๋ฃจํŠธ('/')์—์„œ ์ง์ ‘ ์ ‘์†ํ•˜๋Š” ํŽ˜์ด์ง€๋“ค์„ ์ œ์ž‘ํ–ˆ๋‹ค๋ฉด

    ์ƒ์„ธํŽ˜์ด์ง€๋Š” /parent/child/... ์˜ ํ˜•ํƒœ์ด๋‹ค.

    ์ด๊ฒƒ์„ ์ด์šฉํ•˜๋ฉด url์— ์ผ๊ด€์„ฑ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๊ณ  ์กฐ๊ธˆ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

     

    ์ƒ์„ธํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

    /page/detail1, /page/detail2, ... ์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์”ฉ ๋งŒ๋“ค์–ด๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ,

    ํŽ˜์ด์ง€ ์ˆ˜๋งŒํผ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด๋‚˜๋„ ๋น„ํšจ์œจ์ ์ด๋‹ค.

     

    ์ด๊ฒƒ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฟ์žˆ์ง€๋งŒ ๊ทธ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ URL ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌธ๋ฒ•์ด๋‹ค.

     

    1. URL ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌธ๋ฒ•

    ํ˜•ํƒœ

    /๋ถ€๋ชจurl/:์ž์‹url

    ์œ„์™€ ๊ฐ™์ด /:์ž์‹url ์ด URLํŒŒ๋ผ๋ฏธํ„ฐ ๋ฌธ๋ฒ•์ด๋‹ค.

    ์ด๋ฅผ ์„œ๋ฒ„์— ๋“ฑ๋กํ•˜๋ฉด ๋ถ€๋ชจurl/ ์ž„์˜์˜ ์ž์‹url path์— ์ ‘์†ํ•˜๋ฉด ํ•ด๋‹น URL์„ GET์š”์ฒญํ•œ ๊ฒƒ์œผ๋กœ ์ธ์‹ํ•œ๋‹ค.

     

    ์ด๋•Œ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

     

     

    ์‚ฌ์šฉ๋ฒ•

    app.get('/๋ถ€๋ชจURL/์ž์‹URL', (request, response)=>{
      ...
    })

     

    ์˜ˆ์‹œ

    app.get('/detail/:num', (request, response)=>{
      response.render('detail.ejs');
    })

    detail/:ํŒŒ๋ผ๋ฏธํ„ฐ๋ช… ์„ ์„œ๋ฒ„์— ๋“ฑ๋กํ•˜์˜€๋‹ค.

     

    ์ด ์˜ˆ์‹œ์—์„œ๋Š” DB์— ์ €์žฅ๋˜์–ด์žˆ๋Š” ํฌ์ŠคํŠธ์˜ id๋ฅผ ์ด์šฉํ•ด ํฌ์ŠคํŠธ ๋“ค์„ ๊ฐ€์ ธ์™€๋ณผ ์˜ˆ์ •์ด๋‹ค.

     

     


    2. ์ƒ์„ธ ํŽ˜์ด์ง€ ๊ตฌํ˜„ํ•˜๊ธฐ

    [๊ณผ์ • ์š”์•ฝ]
    1. ์œ ์ €๊ฐ€ /detail/... ์ ‘์†
    2. ์„œ๋ฒ„์—์„œ ํ•ด๋‹น id๋ฅผ ๊ฐ€์ง„ ๋ฐ์ดํ„ฐ๋ฅผ DB์—์„œ ์ฐพ๊ธฐ
    3. ์ฐพ์€ ๋ฐ์ดํ„ฐ๋ฅผ EJSํŒŒ์ผ์— ๋ณด๋‚ด์คŒ

     

    1) ๋ฐ์ดํ„ฐ์— ์ ‘์†ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ (request.params)

    URLํŒŒ๋ผ๋ฏธํ„ฐ์— ์ „๋‹ฌ๋œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” request.params๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

    app.get('/detail/:num', (request, response)=>{
      console.log(request.params)
      response.render('detail.ejs');
    })

     

    ์ด๋ ‡๊ฒŒ ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋กœ num ํŒŒ๋ฆฌ๋ฏธํ„ฐ์— ์ „๋‹ฌ๋œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

     

    2) DB์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

    const { MongoClient, ObjectId} = require('mongodb');
    
    ...
    
    app.get('/detail/:num', async(request, response)=>{
      let result = await db.collection('post').findOne({_id : new ObjectId(request.params.num)})
      response.render('detail.ejs', {result:result});
    })

     

    - findOne() :

    ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ „๋‹ฌ๋œ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด DB์˜ ๋ฐ์ดํ„ฐ๋ธ”๋ก ์ค‘ _id๊ฐ€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ์™€ ๊ฐ™์€ ๊ฒƒ์„ ํ•œ ๊ฐœ ์ฐพ์•„์˜จ๋‹ค.

    ์ด๋ฅผ ์œ„ํ•ด์„œ findOne()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.

     

    - ObjectId():

    MongoDB์˜ ๋ฐ์ดํ„ฐ๋ธ”๋ก์„ ์‚ดํŽด๋ณด๋ฉด _id ์—๋Š” ObjectId()๊ฐ€ ์ผ๋ จ๋ฒˆํ˜ธ๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋‹ค.

     

    ์ด๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€์•ผํ•˜๋ฏ€๋กœ mongodb ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ import ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

    ์ดํ›„ new ObjectId(...)๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ํŠน์ •ํ•œ๋‹ค.

     

    3) EJS ํŒŒ์ผ ์„ค์ •

    {result: result}์˜ ํ˜•ํƒœ๋กœ ํŒŒ์ผ์— ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฝ‚์•„์ค€๋‹ค.

     

     

     


    3. ๋งํฌ ์ƒ์„ฑํ•˜๊ธฐ

    ์ƒ์„ธํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐ€๊ธฐ ์œ„ํ•œ ๋งํฌ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž!

     

    ๋ฐฉ๋ฒ•์€ ์ง€๊ธˆ๊นŒ์ง€ ๋‹ค๋ฃจ์—ˆ๋˜ ๋‚ด์šฉ์„ ๊ทธ๋Œ€๋กœ ํ™œ์šฉํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ

     

    list ํŽ˜์ด์ง€์— ์žˆ๋Š” ๋ธ”๋ก์„ ํด๋ฆญํ•˜๋ฉด ํ•ด๋‹น ๊ธ€์˜ ์ƒ์„ธํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด๋ณด์ž!

     

    1) list.ejs ํŒŒ์ผ ์„ธํŒ…

    //server.js
    app.get('/list', async (request, response) => {
      let result = await db.collection('post').find().toArray();
      console.log(result)
      response.render('list.ejs', {list : result, image:image});
    })

    ejs ํŒŒ์ผ์— ์ „๋‹ฌ๋˜๋Š” ๋ฐ์ดํ„ฐ ์ค‘ result๋Š” DB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ ๋ธ”๋ก์ด๋‹ค.

     

    ๋”ฐ๋ผ์„œ list.ejs ํŒŒ์ผ์—์„œ _id ๋ฅผ ์ด์šฉํ•ด ๋งํฌ๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

    //list.ejs
    
    ...
    <a class="postLink" href="/detail/<%= list[i]["_id"] %>">
      ...
    </a>

    /detail/<%= list[i]["_id"] %> ๋กœ ์ด๋™ํ•˜๋„๋ก ํ•˜๋ฉด ์‚ฌ์ „์— ์ •์˜ํ•œ detail ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๊ฒŒ ๋œ๋‹ค.

     

    ๋!

     

    2) ์ข€ ๋” ์•ˆ์ •์ ์ธ ์„œ๋ฒ„ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด์„œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ

    detail/:num ์„ ํ†ตํ•ด ์ ‘์†ํ• ๋•Œ ๋งŒ์•ฝ ์„œ๋ฒ„์— ๋“ฑ๋ก๋˜์–ด์žˆ์ง€ ์•Š์€ _id๋ฅผ ์ž…๋ ฅํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด

    ์‚ฌ์šฉ์ž์—๊ฒŒ "์กด์žฌํ•˜์ง€ ์•Š๋Š” ํŽ˜์ด์ง€" ๋“ฑ์˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์›Œ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ด๋‹ค!

     

    ๋จผ์ € ์ง์ ‘ ์˜ค๋ฅ˜๋ฅผ ๋„ฃ์–ด๋ณด์ž. 

     

    (1) detail/1 ๋กœ ์ ‘์†ํ–ˆ์„๋•Œ

    ์„œ๋ฒ„ํŒŒ์ผ ๋‚ด์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ ,

    12bytes์˜ string ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•ด์•ผํ•œ๋‹ค๋Š” ์—๋Ÿฌ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

     

    (2) detail/24๊ธ€์ž ๋กœ ์ ‘์†ํ–ˆ์„ ๋•Œ

    ์ด๋ฒˆ์—๋Š” ejs ํŒŒ์ผ์ชฝ์—์„œ null ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ์ฆ‰, DB ์ชฝ์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ null ์ธ ๊ฒƒ์ด๋‹ค.

     

    (3) ๊ฐœ์„ ํ•ด๋ณด๊ธฐ

    app.get('/detail/:num', async(request, response)=>{
      try{
        let result = await db.collection('post').findOne({_id : new ObjectId(request.params.num)})
        if (result == null) {
          response.status(400).send('์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ธ€์ž…๋‹ˆ๋‹ค.')
        } else {
          response.render('detail.ejs', { result : result })
        }
      }
      catch{
        response.send("์˜ค๋ฅ˜!")
      }
    })

    ์œ„์ฒ˜๋Ÿผ try, catch ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ณ  result๊ฐ€ null ์ธ ๊ฒฝ์šฐ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ธ€์ž„์„ ๋ฉ”์„ธ์ง€๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

     

    .status()์— ๋“ค์–ด๊ฐ€๋Š” ์ฝ”๋“œ๋Š”

    ์œ ์ €์˜ ์ž˜๋ชป์ธ ๊ฒฝ์šฐ : 4XX, ์„œ๋ฒ„์˜ ์ž˜๋ชป์ธ ๊ฒฝ์šฐ : 5XX ๋“ฑ์œผ๋กœ ํ‘œ์‹œํ•˜๋ฉฐ

    ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๋ถ€๋ถ„์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

    (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)

     

     

     

    ๋Œ“๊ธ€