diff --git a/ssr/package.json b/ssr/package.json index db1a534..2ef58a6 100644 --- a/ssr/package.json +++ b/ssr/package.json @@ -4,8 +4,8 @@ "description": "SSR 렌더링으로 영화 목록 불러오기", "main": "server/index.js", "scripts": { - "start": "NODE_TLS_REJECT_UNAUTHORIZED=0 node server/index.js", - "dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 nodemon server/index.js --watch" + "start": "set NODE_TLS_REJECT_UNAUTHORIZED=0 && node server/index.js", + "dev": "set NODE_TLS_REJECT_UNAUTHORIZED=0 && nodemon server/index.js --watch" }, "type": "module", "dependencies": { @@ -16,4 +16,4 @@ "nodemon": "^3.1.6", "dotenv": "^16.0.0" } -} +} \ No newline at end of file diff --git a/ssr/server/routes/index.js b/ssr/server/routes/index.js index 84d32f2..9588a04 100644 --- a/ssr/server/routes/index.js +++ b/ssr/server/routes/index.js @@ -1,21 +1,14 @@ import { Router } from "express"; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; +import { renderMovieDetail, renderMovieList } from "../../src/render.js"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); const router = Router(); -router.get("/", (_, res) => { - const templatePath = path.join(__dirname, "../../views", "index.html"); - const moviesHTML = "

들어갈 본문 작성

"; - - const template = fs.readFileSync(templatePath, "utf-8"); - const renderedHTML = template.replace("", moviesHTML); - - res.send(renderedHTML); -}); +router.get("/", renderMovieList); +router.get("/now-playing", renderMovieList); +router.get("/popular", renderMovieList); +router.get("/top-rated", renderMovieList); +router.get("/upcoming", renderMovieList); +router.get("/detail/:id", renderMovieDetail); export default router; diff --git a/ssr/src/api.js b/ssr/src/api.js new file mode 100644 index 0000000..3661844 --- /dev/null +++ b/ssr/src/api.js @@ -0,0 +1,13 @@ +import { FETCH_OPTIONS, TMDB_MOVIE_DETAIL_URL, TMDB_MOVIE_LISTS } from "./constant.js"; + +export const fetchMovieList = async (listType) => { + const response = await fetch(TMDB_MOVIE_LISTS[listType], FETCH_OPTIONS); + + return await response.json(); +}; + +export const fetchMovieDetail = async (id) => { + const response = await fetch(`${TMDB_MOVIE_DETAIL_URL}${id}?language=ko-KR`, FETCH_OPTIONS); + + return await response.json(); +}; \ No newline at end of file diff --git a/ssr/src/constant.js b/ssr/src/constant.js new file mode 100644 index 0000000..8bac807 --- /dev/null +++ b/ssr/src/constant.js @@ -0,0 +1,28 @@ +export const BASE_URL = "https://api.themoviedb.org/3/movie"; + +export const TMDB_THUMBNAIL_URL = "https://media.themoviedb.org/t/p/w440_and_h660_face/"; +export const TMDB_ORIGINAL_URL = "https://image.tmdb.org/t/p/original/"; +export const TMDB_BANNER_URL = "https://image.tmdb.org/t/p/w1920_and_h800_multi_faces/"; +export const TMDB_MOVIE_LISTS = { + POPULAR: BASE_URL + "/popular?language=ko-KR&page=1", + NOW_PLAYING: BASE_URL + "/now_playing?language=ko-KR&page=1", + TOP_RATED: BASE_URL + "/top_rated?language=ko-KR&page=1", + UPCOMING: BASE_URL + "/upcoming?language=ko-KR&page=1", +}; +export const TMDB_MOVIE_DETAIL_URL = "https://api.themoviedb.org/3/movie/"; + +export const FETCH_OPTIONS = { + method: "GET", + headers: { + accept: "application/json", + Authorization: "Bearer " + process.env.TMDB_TOKEN, + }, +}; + +export const URL_TO_MOVIE_LIST = { + "/": "NOW_PLAYING", + "/now-playing": "NOW_PLAYING", + "/popular": "POPULAR", + "/top-rated": "TOP_RATED", + "/upcoming": "UPCOMING", +}; diff --git a/ssr/src/html.js b/ssr/src/html.js new file mode 100644 index 0000000..342d9fd --- /dev/null +++ b/ssr/src/html.js @@ -0,0 +1,74 @@ +import { TMDB_THUMBNAIL_URL } from "./constant.js"; + +export const getMovieListHTML = (movieItems = []) => movieItems.map( + ({ id, title, backdrop_path: thumbnail, vote_average: rate }) => /*html*/ ` +
  • + +
    + ${title} +
    +

    ${rate}

    + ${title} +
    +
    +
    +
  • + ` +).join(''); + +export const getMovieDetailHTML = (movieDetail) => /*html*/ ` + + + + `; \ No newline at end of file diff --git a/ssr/src/render.js b/ssr/src/render.js new file mode 100644 index 0000000..4d69f1a --- /dev/null +++ b/ssr/src/render.js @@ -0,0 +1,33 @@ +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import { getMovieDetailHTML, getMovieListHTML } from "../src/html.js"; +import { fetchMovieDetail, fetchMovieList } from "../src/api.js"; +import { URL_TO_MOVIE_LIST } from "./constant.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export const renderMovieList = async (req, res) => { + const templatePath = path.join(__dirname, "../views", "index.html"); + const movieListType = URL_TO_MOVIE_LIST[req.url]; + + const movieList = (await fetchMovieList(movieListType)).results; + const movieListHTML = getMovieListHTML(movieList); + const template = fs.readFileSync(templatePath, "utf-8"); + const renderedHTML = template.replace("", movieListHTML); + + res.send(renderedHTML); +}; + +export const renderMovieDetail = async (req, res) => { + const templatePath = path.join(__dirname, "../views", "index.html"); + const { id } = req.params; + + const movieDetail = await fetchMovieDetail(id); + const movieDetailHTML = getMovieDetailHTML(movieDetail); + const template = fs.readFileSync(templatePath, "utf-8"); + const renderedHTML = template.replace("", movieDetailHTML); + + res.send(renderedHTML); +}; \ No newline at end of file