Team Project | Marple shop - My work

Wookยท2022๋…„ 2์›” 3์ผ
0

[Project] Team Project | Marple shop WEB

๋ชฉ๋ก ๋ณด๊ธฐ
2/2
post-thumbnail

๐Ÿ“ฒ ํŒ€ ํ”„๋กœ์ ํŠธ

10์›” ์ค‘์ˆœ๋ถ€ํ„ฐ ์‹œ์ž‘๋œ ์œ„์ฝ”๋“œ ํ’€์Šคํƒ ๋ถ€ํŠธ์บ ํ”„, ๊ทธ๊ฐ„ JavaScript, HTML, CSS๋ฅผ ํ†ตํ•ด ๊ธฐ์ดˆ๋ฅผ ๋‹ค์ง€๋ฉฐ, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” ๋” ๋‚˜์•„๊ฐ€ React, SASS ๋ฐฑ์—”๋“œ์—์„œ๋Š” Node.js, Express, MySQL๊ณผ MVC Pattern์„ ์ ์šฉํ•œ Layered pattern, ์„œ๋ฒ„์™€ ํ†ต์‹  ๊ณผ์ • ๋“ฑ์„ ํ•™์Šตํ•˜๋ฉฐ, ๊ทธ๊ฐ„์˜ ํ•™์Šต ๊ณผ์ •์„ ๋‹ค์ง€๊ธฐ ์œ„ํ•œ ํŒ€ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•œ ํŒ€๋‹น 4~5๋ช…์˜ ๊ตฌ์„ฑ์›์„ ์ด๋ค„ ํ‰์†Œ ํŒ€์›๋“ค์ด ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ํด๋ก  ์ฝ”๋”ฉํ•˜๋ฉฐ, ๊ทธ๊ฐ„ ๋ฐฐ์šด ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ๊ธฐ์ˆ ๋“ค์„ ์ ์šฉํ•ด๋ณด๋ฉฐ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์„ ์ ๊ฒ€ํ•˜๊ณ , ๊ณต๋ถ€ํ–ˆ๋˜ ๋ถ€๋ถ„์„ ๋ณต์Šตํ•˜๋ฉฐ, ํ”„๋กœ์ ํŠธ์—์„œ ํ•„์š”ํ•œ ๊ธฐ์ˆ ๋“ค์„ ๋” ๋ฐฐ์šฐ๊ณ  ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š”, ์—ฌ๋Ÿฌ๋ชจ๋กœ ์žฅ์ ์ด ๋งŽ์€ ํ”„๋กœ์ ํŠธ์˜€๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ญ๋‹ˆ๋‹ค.


โญ๏ธ Team : Wepleshop

์šฐ๋ฆฌ ํŒ€์€ Marple Shop ํ™ˆํŽ˜์ด์ง€๋ฅผ ํด๋ก  ์ฝ”๋”ฉํ•˜๊ธฐ๋กœ ์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ™ˆํŽ˜์ด์ง€๋Š” ํฐ ๋ฒ”์ฃผ๋กœ ๋ฉ”์ธ ํŽ˜์ด์ง€, ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€, ์ƒ์„ธ ํŽ˜์ด์ง€, ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๋กœ ๋‚˜๋‰˜์–ด์กŒ์œผ๋ฉฐ, ํŒ€์›์ด 5๋ช…์ด์—ˆ๋˜ ์šฐ๋ฆฌ ํŒ€์€ ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ํ”„๋กœ์ ํŠธ์˜ ๋น„์ค‘์ด ํด ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ, ์Šฌ๋ผ์ด๋“œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ์—ญํ• ์„ ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ ๋ถ„๋ฆฌํ•˜์—ฌ, ํ™ˆํŽ˜์ด์ง€์˜ 4๊ฐœ์˜ ๋ฒ”์ฃผ, ๊ทธ๋ฆฌ๊ณ  ์Šฌ๋ผ์ด๋“œ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜์—ฌ ์ด 5๊ฐ€์ง€์˜ ์—ญํ• ์„ ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ์—์„œ ๊ฐ์ž 1๊ฐœ์”ฉ ์—ญํ• ์„ ๋งก์•„ ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ ์ œ ์—ญํ• ์€ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ๋Š” ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ / ๋ฐฑ์—”๋“œ์—์„œ๋Š” ๋กœ๊ทธ์ธ / ํšŒ์›๊ฐ€์ž… ์„ ๋งก๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, ์ดํ›„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์‚ฌํ•ญ์—์„œ ์ข‹์•„์š” ๊ธฐ๋Šฅ ๊ณผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ถ”๊ฐ€, ์‚ญ์ œ, ์ˆ˜์ • ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


โญ๏ธ ํ”„๋กœ์ ํŠธ ๊ตฌํ˜„ ์˜์ƒ

(ํ•˜๋‹จ ์ด๋ฏธ์ง€ ํด๋ฆญ์‹œ, Youtube ๋งํฌ๋กœ ์ „ํ™˜๋ฉ๋‹ˆ๋‹ค!)


๐ŸŽฑ ๊ตฌํ˜„ ๊ธฐ๋Šฅ

Back-end

  • MySQL์„ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ (๊ณตํ†ต)

  • ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… API (๋‚˜์˜ ์—ญํ• )

    • ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๊ธฐ๋Šฅ
    • JWT์„ ํ™œ์šฉํ•œ ํ† ํฐ ๋ฐœํ–‰
    • Bcrypt๋ฅผ ํ™œ์šฉํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
    • ๋กœ๊ทธ์ธ์‹œ token์„ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ด๋ฆ„ ํ˜ธ์ถœ ๊ตฌํ˜„
  • ์นดํ…Œ๊ณ ๋ฆฌ API

    • 1์ฐจ ์นดํ…Œ๊ณ ๋ฆฌ, 2์ฐจ ์นดํ…Œ๊ณ ๋ฆฌ ๋ฆฌ์ŠคํŠธ
  • ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ & ํ•„ํ„ฐ๋ง & ์ •๋ ฌ API

    • ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ด์šฉํ•œ ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ ํ•„ํ„ฐ๋ง ๊ตฌํ˜„
  • ์ƒํ’ˆ ์ƒ์„ธ API

    • ํŠน์ • ์ƒํ’ˆ์˜ ์žฌ๊ณ , ์ƒ‰์ƒ, ์‚ฌ์ด์ฆˆ, ์ด๋ฏธ์ง€ ํ˜ธ์ถœ
  • Carousel API

    • ์Šฌ๋ผ์ด๋“œ ์ด๋ฏธ์ง€, ํƒ€์ดํ‹€, ๋””์Šคํฌ๋ฆฝ์…˜ ํ˜ธ์ถœ
  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์Šฌ๋ผ์ด๋“œ API

    • ์ด๋ฏธ์ง€, alt๊ฐ’ ํ˜ธ์ถœ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ API (๋‚˜์˜ ์—ญํ• )

    • ๋””ํ…Œ์ผ ํŽ˜์ด์ง€์—์„œ ์ œํ’ˆ ์ •๋ณด๋ฅผ ๋ฐ›์•„ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ถ”๊ฐ€
    • ์ค‘๋ณต๋˜๋Š” ์ œํ’ˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ถ”๊ฐ€์‹œ ์ˆ˜๋Ÿ‰์„ ์ถ”๊ฐ€
    • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‚ด ์ œํ’ˆ์˜ ์‚ญ์ œ ๋ฐ ์ˆ˜๋Ÿ‰ ๋ณ€๊ฒฝ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ์ข‹์•„์š” API (๋‚˜์˜ ์—ญํ• )

    • ์œ ์ € ์ •๋ณด์™€ ์ œํ’ˆ ์ •๋ณด์— ๋”ฐ๋ฅธ ์ข‹์•„์š” ๊ธฐ๋Šฅ ๊ตฌํ˜„

Front-end

๊ณตํ†ต

  • ํšŒ์›๊ฐ€์ž… / ๋กœ๊ทธ์ธ / ๋งˆ์ดํŽ˜์ด์ง€

    • ์•„์ด๋”” ํŒจ์Šค์›Œ๋“œ ์œ ํšจ์„ฑ ๊ฒ€์ฆ ๊ธฐ๋Šฅ ๋ฐ ์‹คํŒจ์‹œ ๋ชจ๋‹ฌ์ฐฝ ์ƒ์„ฑ
    • ๋กœ๊ทธ์ธ์‹œ ๋ฐฑ์—”๋“œ API๋ฅผ ์ด์šฉํ•ด ํ† ํฐ ๋ฐœํ–‰
  • Top / Footer / Nav

    • ๊ฐ ๋ถ€๋ถ„ ์ปดํฌ๋„ŒํŠธํ™”ํ•˜์—ฌ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„

๋ฉ”์ธ ํŽ˜์ด์ง€

  • ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ API ํ˜ธ์ถœํ•˜์—ฌ UI ๊ตฌํ˜„

    • ์ƒํ’ˆ ์ข‹์•„์š” ๊ธฐ๋Šฅ
    • ์žฌ๊ณ  10๊ฐœ ๋ฏธ๋งŒ์ผ ๋•Œ ์žฌ๊ณ  ๊ณ ์ง€ ๋ฐ ํ’ˆ์ ˆ์‹œ ํ’ˆ์ ˆ ๊ณ ์ง€
    • ์ƒํ’ˆ ํ•„ํ„ฐ๋ง๊ธฐ๋Šฅ
  • Carousel UI ๊ตฌํ˜„

    • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—†์ด ์ž์ฒด ๊ตฌํ˜„
    • ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ, ์™ผ์ชฝ ๋ฒ„ํŠผ ์ƒ๊ด€์—†์ด ์ œ๋Œ€๋กœ ์ž‘๋™
  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์Šฌ๋ผ์ด๋“œ UI๊ตฌํ˜„

    • ์ขŒ์šฐ๋กœ ๋ฌดํ•œํžˆ ์ด๋™ํ•˜๋Š” ์Šฌ๋ผ์ด๋“œ

์ƒ์„ธ ํŽ˜์ด์ง€ (๋‚˜์˜ ์—ญํ• )

  • ์ œํ’ˆ๋ณ„ ์ƒ‰์ƒ, ์‚ฌ์ด์ฆˆ, ๊ฐ€๊ฒฉ ์ ์šฉ ๋ฐ ์„ ํƒ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ์„ ํƒ๋œ ๋ฐ์ดํ„ฐ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ถ”๊ฐ€
  • ์ œํ’ˆ ์ด๋ฏธ์ง€ ์Šฌ๋ผ์ด๋“œ / ์ข‹์•„์š” ๊ธฐ๋Šฅ ๊ตฌํ˜„

์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€

  • ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ๋ถˆ๋Ÿฌ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ UI๋กœ ๊ตฌํ˜„
  • ๋กœ๊ทธ์ธ์‹œ ๋ถ€์—ฌ๋œ ํ† ํฐ์„ ์ด์šฉํ•ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธด ์ƒํ’ˆ์˜ ๊ณ„์‚ฐ ๊ธฐ๋Šฅ

๐ŸŒˆ My work (Back-end)

๋ฐฑ์—”๋“œ์—์„œ๋Š” ๋กœ๊ทธ์ธ ํšŒ์›๊ฐ€์ž… API, ์žฅ๋ฐ”๊ตฌ๋‹ˆ API, ์ข‹์•„์š” API ๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
๋ณธ๋ž˜๋Š” ๋กœ๊ทธ์ธ ํšŒ์›๊ฐ€์ž… API ๋งŒ์ด ์ €์˜ ์—ญํ• ์ด์—ˆ์ง€๋งŒ, ํ”„๋ก ํŠธ์—”๋“œ์—์„œ์˜ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ ์ž‘์—…์„ ํ•˜๋ฉด์„œ, ๊ฐ€๊ณต๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋“ค์„ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€์— ์ ํ•ฉํ•˜๊ฒŒ ๊ฐ€๊ณตํ•˜๋Š” ์ž‘์—…์„ ๊ฑฐ์น˜๋ฉด์„œ, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋“ค์„ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ด์šฉํ•˜๋Š”๊ฒŒ ํŽธ๋ฆฌํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€์œผ๋ฉฐ (ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ–ˆ์„ ๋•Œ ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์ด์—ˆ์Šต๊ธฐ์—, 2์ฐจ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ๋ฐฉํ–ฅ์„ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.) ์ข‹์•„์š” ๊ธฐ๋Šฅ ๊ตฌํ˜„๋„ CRUD์˜ CD๋ฅผ ํ™œ์šฉํ•œ๋‹ค๋ฉด ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐ๋˜์–ด ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๋งก์•˜์Šต๋‹ˆ๋‹ค.

โ›ณ๏ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๋กœ๊ทธ์ธ ํšŒ์›๊ฐ€์ž…

(ํšŒ์›๊ฐ€์ž… ๊ณผ์ •)

(๋กœ๊ทธ์ธ ๊ณผ์ •)

userServices.js (MVC Pattern์„ ์ ์šฉํ•œ Service๋‹จ, bcrypt ํ™œ์šฉ)

const { userDao, productCartDao } = require('../models/');
const bcrypt = require('bcrypt');
const token = require('../utils/token');

const signIn = async (email, password) => {
  const user = await userDao.getUserByEmail(email);

  const isSame = bcrypt.compareSync(password, user.password);

  if (!user) {
    const error = new Error('INVALID_USER');
    error.statusCode = 400;

    throw error;
  }

  if (!isSame) {
    const error = new Error('INVALID_USER');
    error.statusCode = 400;

    throw error;
  }
  const signToken = token.signToken(user.email);
  return signToken;
};

const signUp = async (name, email, password) => {
  const userData = await userDao.getUserByEmail(email);

  if (userData) {
    const error = new Error('EMAIL IS DUPLICATED');
    error.statusCode = 400;

    throw error;
  }

  const hashedPassword = bcrypt.hashSync(password, 10);
  return await userDao.createUser(name, email, hashedPassword);
};

utils/token.js (JWT ๋ณตํ˜ธํ™” ๊ณผ์ •)

const jwt = require('jsonwebtoken');

const salt = 'SALTSALTSALT';

const signToken = (email) => {
  return jwt.sign({ id: email }, salt, { expiresIn: '30m' });
};

const verifyToken = (token) => {
  try {
    return jwt.verify(token, salt);
  } catch (err) {
    return null;
  }
};

module.exports = { signToken, verifyToken };

JWT, Bcrypt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”์‹œ์ผœ ์ €์žฅํ•ด์ฃผ๋„๋ก ํ•ด์ฃผ๊ณ , userDao์—์„œ ๋ฐ›์•„์˜จ user์˜ email์„ JWT๋ฅผ ํ†ตํ•ด ํ† ํฐ์œผ๋กœ ๋ฐœํ–‰ํ•ด์ฃผ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


๋””ํ…Œ์ผ ํŽ˜์ด์ง€, ์žฅ๋ฐ”๊ตฌ๋‹ˆ API (ํ”„๋ก ํŠธ์—”๋“œ & ๋ฐฑ์—”๋“œ)

ํ”„๋ก ํŠธ ์—”๋“œ์—์„œ ์ œ ์—ญํ• ์€ ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. HTML, CSS, React ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ชจ๋“  ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌํ˜„ํ•˜์˜€์œผ๋ฉฐ, ๋””ํ…Œ์ผ ํŽ˜์ด์ง€ API์˜ ๋ฐ์ดํ„ฐ๋“ค์„ ํ†ตํ•ด ์ œํ’ˆ ์ด๋ฏธ์ง€, ์‚ฌ์ด์ฆˆ ์ƒ‰์ƒ ์„ ํƒ์ฐฝ๊ณผ ๊ฐ€๊ฒฉ์„ React์˜ useState()๋ฅผ ํ†ตํ•ด ์„ค์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์‚ฌ์ด์ฆˆ ํ˜น์€ ์ƒ‰์ƒ์ด ์„ ํƒ๋˜์ง€ ์•Š๊ณ  ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ๋ฅผ ๋ˆ„๋ฅผ ๊ฒฝ์šฐ์—” ํ•ด๋‹น ๊ฒฝ์šฐ์— ๋”ฐ๋ฅธalert()์ฐฝ์„ ๊ตฌํ˜„ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ์—์„œ ๊ตฌํ˜„ํ•œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋””ํ…Œ์ผ ํŽ˜์ด์ง€์˜ ์ œํ’ˆ ์ •๋ณด์™€ ์œ ์ €๊ฐ€ ์„ ํƒํ•œ ์‚ฌ์ด์ฆˆ, ์ƒ‰์ƒ, ์ˆ˜๋Ÿ‰ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ carts ํ…Œ์ด๋ธ”์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

CRUD์˜ Delete ๋ฅผ ํ†ตํ•ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์˜ ์‚ญ์ œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ carts ํ…Œ์ด๋ธ”์—์„œ ํ•ด๋‹น ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•ด์ฃผ๋„๋ก ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๐ŸŽฑ ํšŒ๊ณ 

ํ˜„์žฌ ์ด ๊ธ€์„ ์“ฐ๋Š” ์‹œ์ ์€ 2์ฐจ ํ”„๋กœ์ ํŠธ์ธ ๋‚˜์ดํ‚ค ํด๋ก ์ฝ”๋”ฉ ํ”„๋กœ์ ํŠธ๊นŒ์ง€ ๋ชจ๋‘ ์™„๋ฃŒ๋œ ์ƒํ™ฉ์—์„œ ์ž‘์„ฑํ•˜๋Š” ํฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. 1์ฐจ ํ”„๋กœ์ ํŠธ์ธ๋งŒํผ ๋ถ€์กฑํ•œ ์ ์ด ๋งŽ์•˜์œผ๋ฉฐ, ์ €์˜ ๋ถ€์กฑํ•œ ์ ์„ 1์ฐจ ํ”„๋กœ์ ํŠธ์—์„œ ๊นจ๋‹ฌ์•˜๊ธฐ์— 2์ฐจ ํ”„๋กœ์ ํŠธ์—์„œ ํ•ด๋‹น ๋ถ€๋ถ„๋“ค์„ ๊ฐœ์„ ํ•˜๊ณ  ๋ณด์™„ํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ์— ํฐ ์˜๋ฏธ๊ฐ€ ์žˆ๋˜ ํ”„๋กœ์ ํŠธ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๋ฌด์—‡๋ณด๋‹ค ํŒ€๊ณผ์˜ ํ˜‘์—…์—์„œ์˜ ์–ด๋–ค ํฌ์ง€์…˜์— ์ง‘์ค‘์„ ํ•ด์•ผ ํ•˜๋ฉฐ, Git ํ˜‘์—…์— ๋Œ€ํ•œ ํƒœ๋„์™€ ๊ธฐ์ˆ  ๋“ฑ์„ ๋ถ€๋”ชํžˆ๋ฉฐ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ๊ธฐ์—, ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ–์ถฐ์•ผํ•  ์ž์„ธ๋ฅผ ๋ฐฐ์› ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
MVC Pattern, REST API ์˜ ์ ์šฉ ๋“ฑ๋„ ์ต์ˆ™ํ•ด์งˆ ์ˆ˜ ์žˆ์—ˆ์œผ๋ฉฐ, ํ•ด๋‹น ๊ธฐ์ˆ ๋“ค์˜ ํ•„์š”์„ฑ์„ ๋”์šฑ ์ ˆ์‹คํžˆ ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค.
์ดˆ๊ธฐ Modeling ๊ณผ์ •์˜ ์ค‘์š”์„ฑ, ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ดํ•ด์™€ ํ™œ์šฉ ์—ญ์‹œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ์จ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ๋‹ค๋ค„์•ผํ•  ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์œผ๋ฉฐ, ์ €๋Š” ์ด ๋ถ€๋ถ„์—์„œ ์žฌ๋ฏธ์žˆ๊ณ , ํฅ๋ฏธ๋ฅผ ๋Š๋ผ๋ฉฐ ์‹œ๊ฐ„ ๊ฐ€๋Š”์ค„ ๋ชฐ๋ž๋˜ ์ œ ๋ชจ์Šต์„ ๋ดค์œผ๋ฉฐ, ํ”„๋ก ํŠธ ์—”๋“œ๋„ ์ข‹์ง€๋งŒ ๋ฐฑ์—”๋“œ์ชฝ์œผ๋กœ ๋งˆ์Œ์„ ๊ตณํžˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
2์ฐจ ํ”„๋กœ์ ํŠธ๋งˆ์ € ๋๋‚œ ํ˜„ ์‹œ์ ์œผ๋กœ ์•„์ง๋„ ๋ฐฐ์›Œ์•ผ ํ•˜๊ณ  ๊ณต๋ถ€ํ•ด์•ผํ•  ์‚ฐ๋“ค์ด ๋งŽ์Šต๋‹ˆ๋‹ค.
๋ถ€๋”ชํžˆ๊ณ  ๋„˜์–ด์ ธ๋„, ๊ณ„์†ํ•ด์„œ ๋‹ค์‹œ ์ผ์–ด๋‚˜๋ฉฐ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ  ์‹ถ๋‹ค๋Š” ํฌ๋ถ€๊ฐ€ ์ƒ๊ธฐ๋Š” ํ”„๋กœ์ ํŠธ์˜€์Šต๋‹ˆ๋‹ค. ๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

profile
์ง€์†์ ์œผ๋กœ ์„ฑ์žฅํ•˜๊ณ  ๋ฐœ์ „ํ•˜๋Š” ์ง„์ทจ์ ์ธ ํƒœ๋„๋ฅผ ๊ฐ€์ง„ ๊ฐœ๋ฐœ์ž์˜ ์‚ถ์„ ์ถ”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€