본문 바로가기
데이터베이스

mongoose-express 상세페이지 만들기

by 즐거운코딩 2023. 8. 12.
반응형

앞서서 mongose와 express를 통해서 기본적인 CRUD 기능을 만들어 볼 수 있습니다.

일반적인 커머스 사이트에서 상품 목록을 선택하면 상세 페이지에서 해당 상품의 세부 내용을 확인할 수 있습니다.

이제 데이터베이스에 등록한 Product 리스트를 조회하는 페이지를 만들었고, 이제 단일 Product의 상세 페이지를 만들어 보겠습니다.

 

Product를 조회하기 위해 URI에 Product 이름의 경우 중복이 될 수 있으므로 중복되지 않는 mongoDB의 id 를 사용하도록 합니다.  

Product 이름의 중복, 띄어 쓰기 등 여러가지 문제 발생 사항을 고려하여 고유값인 URL Slugs 를 이용하면 됩니다.

 

What is URL slug ?

더보기

A URL slug is a part that comes at the very end of a URL and is the exact address of a specific page on your website. For example - in https://slugify.online/campaign-url-builder URL, "campaign-url-builder" is a slug. Composing a short but descriptive slug for a URL of the web page can positively affect your page's SEO.

 

Product의 mongo _id 로 products 테이블에서 해당 id의 Product 데이터를 조회 되도록 아래와 같이 작성합니다.

const express = require("express");
const app = express();
const path = require("path");
const Product = require("./models/product");

const mongoose = require("mongoose");
mongoose
  .connect("mongodb://127.0.0.1:27017/farmStand", { useNewUrlParser: true })
  .then(() => {
    console.log("mongo connection open !!!");
  })
  .catch((err) => {
    console.log("OH NO mongo connection error !!!");
    console.log(err);
  });

app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");

app.get("/products", async (req, res) => {
  const products = await Product.find({});
  res.render("products/index", { products });
});

app.get("/products/:id", async (req, res) => {
  const { id } = req.params;
  const product = await Product.findById(id);
  console.log(product);
  res.send("detail page!");
});

app.listen(3000, () => {
  console.log("APP IS LISTENING ON PORT 3000!");
});

아래와 같이 products 테이블에서 "Organic Mini Seedless Watermelon" 에 해당되는 id 값으로 URL 를 조회해 봅니다.

터미널에서도 id에 해당되는 product 데이터가 정상적으로 출력됩니다.

 

이제 상세페이지를 만들어 봅니다. views/products/show.ejs 로 product 데이터를 넘겨줍니다.

(...)
app.get("/products", async (req, res) => {
  const products = await Product.find({});
  res.render("products/index", { products });
});

app.get("/products/:id", async (req, res) => {
  const { id } = req.params;
  const product = await Product.findById(id);
  console.log(product);
  res.render("products/show", { product });
});
(...)

products/show.ejs 파일명으로 상세페이지를 만듭니다.

product에 해당되는 상품명, 가격, 카테고리 정보를 출력합니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= product.name %></title>
  </head>
  <body>
    <h1><%= product.name %></h1>
    <ul>
      <li>Price $<%= product.price %></li>
      <li>Category <%= product.category %></li>
    </ul>
  </body>
</html>

이와 같이 개별 Id 를 알아서 직접 입력할 수는 없으니 index 페이지에 있은 상품마다 show페이지를 이동하는 링크를 만듭니다.

 

  (...)
  <body>
    <h1>All Products!</h1>
    <ul>
      <% for (let product of products) { %>
      <li><a href="/products/<%= product._id %>"><%=product.name %></a></li>
      <% } %>
    </ul>
  </body>
  (...)

그리고 상세 페이지에서 다시 전체 목록 페이지로 돌아가는 링크도 만들어 줍니다.

  (...)
  <body>
    <h1><%= product.name %></h1>
    <ul>
      <li>Price $<%= product.price %></li>
      <li>Category <%= product.category %></li>
    </ul>
    <a href="/products">All Products</a>
  </body>
  (...)

지금까지 전체 목록에서 선택한 개별 상품의 상세페이지로 넘어가는 기능을 만들어 보았습니다. 

반응형