๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿคท๐Ÿผโ€โ™€๏ธ Etc.../- old dev log

[Best Of the Best ํ™œ๋™๊ธฐ] 1์ฐจ ํŒ€ ํ”„๋กœ์ ํŠธ ํ›„๊ธฐ - ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๊ฐœ๋ฐœํ•˜๋ฉฐ ํ–ˆ๋˜ ๊ณ ๋ฏผ๋“ค

by Wonit 2021. 8. 25.

์˜ค๋Š˜์€ BoB 10๊ธฐ ๋ณด์•ˆ์ œํ’ˆ๊ฐœ๋ฐœ ํŠธ๋ž™์˜ ๋ณด์•ˆ ์†”๋ฃจ์…˜ ์ œ์ž‘ ์ˆ˜์—…์—์„œ ํ•œ๋‹ฌ๋™์•ˆ ์ง„ํ–‰ํ•œ 1์ฐจ ํŒ€ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•ด๋ณด๋ ค ํ•œ๋‹ค.

ํ•ด๋‹น ๊ธ€์€ ์ด 5๋ถ€์ž‘์œผ๋กœ ํŒ€ ๋นŒ๋”ฉ๊ณผ ํ˜‘์—… ๊ณผ์ • ๊ทธ๋ฆฌ๊ณ  ์„œ๋น„์Šค ์„ค๋ช… ๋ฐ ๊ฐœ๋ฐœ ๊ณผ์ • ์œผ๋กœ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ github ๋ฐ”๋กœ๊ฐ€๊ธฐ -> ๋ณด์•ˆ ์œ„ํ˜‘ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„ ์†”๋ฃจ์…˜ github

 

GitHub - dhslrl321/L7-monitor: ๐Ÿ” L7 ์—์„œ ๋™์ž‘ํ•˜๋Š” Access Log ๊ธฐ๋ฐ˜ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„ ๋ฐ ๋ณด์•ˆ ์œ„ํ˜‘ ๋ถ„์„ ์„œ๋น„์Šค

๐Ÿ” L7 ์—์„œ ๋™์ž‘ํ•˜๋Š” Access Log ๊ธฐ๋ฐ˜ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„ ๋ฐ ๋ณด์•ˆ ์œ„ํ˜‘ ๋ถ„์„ ์„œ๋น„์Šค (BoB 10 ๊ธฐ ๋ณด์•ˆ์ œํ’ˆ๊ฐœ๋ฐœ 1์ฐจ ํŒ€ ํ”„๋กœ์ ํŠธ) - GitHub - dhslrl321/L7-monitor: ๐Ÿ” L7 ์—์„œ ๋™์ž‘ํ•˜๋Š” Access Log ๊ธฐ๋ฐ˜ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„ ๋ฐ ๋ณด

github.com

 

์ง€๋‚œ ์‹œ๊ฐ„ ์šฐ๋ฆฌ๊ฐ€ ํ–ˆ๋˜ ๊ณ ๋ฏผ๋“ค๊ณผ ๋ฌธ์ œ๋“ค, ๊ทธ๋ฆฌ๊ณ  ํ˜‘์—…์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค.

 

์˜ค๋Š˜์€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœํ•œ ์„œ๋น„์Šค๋ฅผ ์ข€ ๋” ๊ธฐ์ˆ ์ ์ธ ๊ด€์ ์—์„œ ์•Œ์•„๋ณด๋ ค ํ•œ๋‹ค.

 

๊ฐœ๋ฐœํ•˜๋Š” ๊ณผ์ •์ด ์–ด๋–ป๊ฒŒ ์ง„ํ–‰๋˜๊ณ  ์–ด๋–ค ๋ฌธ์ œ๋“ค์„ ๋งŒ๋‚ฌ์œผ๋ฉฐ ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์ทจํ–ˆ๋Š”์ง€!

 

๋‚˜๋Š” Web ํŒŒํŠธ๋ฅผ ๋งก์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ ๊ฐœ๋ฐœํ•œ ๊ธฐ๋Šฅ๊ณผ API์— ๋Œ€ํ•ด์„œ๋งŒ ์„ค๋ช…์„ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค ใ…Žใ…Ž..

 

์„œ๋น„์Šค ๊ตฌ์กฐ

 

์šฐ์„  ์„œ๋น„์Šค์˜ ๋ชฉ์ ์€ ์ง€๋‚œ ์‹œ๊ฐ„์— ์ด์•ผ๊ธฐํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ Access Log ๊ธฐ๋ฐ˜ ํŠธ๋ž˜ํ”ฝ ๋ถ„์„ ๋ฐ ๋ณด์•ˆ ์œ„ํ˜‘ ๋ถ„์„ ์ด๋‹ค.

 

์‚ฌ๋‚ด์˜ Web Application ์ด ๊ธฐ์กด์— ์Œ“์•„๋†“๋˜ Access Log ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ๋ถ„์„ํ•˜๊ณ  ๋ณด์•ˆ ์œ„ํ˜‘์„ ์‹œ๊ฐํ™” ํ•ด์ค€๋‹ค.

 

์„œ๋น„์Šค์˜ ํฐ ํ”Œ๋กœ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

์„œ๋น„์Šค ํ”Œ๋กœ์šฐ

 

  1. ๊ณ ๊ฐ์‚ฌ๋Š” ๊ธฐ์กด์— ์šด์˜์ค‘์ด๋˜ ์„œ๋ฒ„์™€ ํ•ด๋‹น ์„œ๋ฒ„๊ฐ€ ์ €์žฅํ•˜๋Š” access.log ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
  2. ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ๋ฐœํ•œ Agent ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
  3. ํ•ด๋‹น Agent์—์„œ access log ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ•˜๊ณ  ๋ถ„์„ ์„œ๋ฒ„๋กœ access log ๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
  4. ์šด์˜ ์„œ๋ฒ„์˜ ์„ฑ๋Šฅ์„ ์œ„ํ•ด์„œ ๋ถ„์„์€ ๋‹ค๋ฅธ ์„œ๋ฒ„์—์„œ ์ง„ํ–‰ํ•œ๋‹ค.
  5. ๋ถ„์„ ์„œ๋ฒ„๋กœ ๋“ค์–ด์˜จ access log ๋Š” ๋ถ„์„์„ ์ง„ํ–‰ํ•˜์—ฌ ๊ณต๊ฒฉ ์œ ํ˜•์— ๋”ฐ๋ผ์„œ DB์— ์ €์žฅํ•œ๋‹ค.
  6. ํ•ด๋‹น DB ์˜ ๊ฐ’๋“ค์„ ํ† ๋Œ€๋กœ ๋ณด์•ˆ ๋ ˆ๋ฒจ์„ ์‚ฐ์ถœํ•˜๊ณ  ๊ฐ์ข… ์‹œ๊ฐํ™”์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ œํ•˜์—ฌ Front๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  7. Front Server๋Š” Backend ์—๊ฒŒ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์‹œ๊ฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

์›๋ž˜ ์ฒ˜์Œ ๊ธฐํš์€ SaaS ํ˜•ํƒœ์˜€๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„์„ ์„œ๋ฒ„๋Š” ์šฐ๋ฆฌ๊ฐ€ ์šด์˜ํ•˜๋Š” ์„œ๋ฒ„์—ฌ์•ผ ํ•˜์ง€๋งŒ ์‹œ๊ฐ„์  ๋ฌธ์ œ๋กœ ์ธํ•ด On-Premise ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค.

 

์ฆ‰, Client๋Š” ๊ธฐ์กด์— ์šด์˜์ค‘์ด๋˜ ์„œ๋ฒ„ + ๋ถ„์„ ์„œ๋ฒ„๋ฅผ ์šด์˜ํ•˜๋Š” ๋ฐฉํ–ฅ์ธ๋ฐ, ์ด๊ฒŒ ์กฐ๊ธˆ ์„œ๋น„์Šค ๊ด€์ ์—์„œ ๋งŽ์€ ์˜๋ฌธ๊ณผ ๋น„ํšจ์œจ์ด ์กด์žฌํ•œ๋‹ค.

 

์–ด์ฉ” ์ˆ˜ ์—†๋‹ค๊ณ  ํƒ€ํ˜‘ํ–ˆ์ง€๋งŒ ์•„์ง ๋งŽ์ด ์•„์‰ฝ๋‹ค..

 

ํ”„๋ก ํŠธ์—”๋“œ์˜ ๊ธฐ์ˆ ์  ๊ณ ๋ฏผ

 

์•ž์„œ ์ด์•ผ๊ธฐํ–ˆ๋“ฏ, ์šฐ๋ฆฌ๋Š” Front End๋ฅผ React๋กœ ๊ฐœ๋ฐœํ•˜์˜€๋‹ค.

 

์ด ๊ณผ์ •์—์„œ ํ–ˆ๋˜ ๊ณ ๋ฏผ๋“ค์€ ํฌ๊ฒŒ 3๊ฐ€์ง€ ์ด๋‹ค.

 

  1. HTML Rendering Server ์˜ ๊ฒฐ์ •
  2. ๋ฆฌ์•กํŠธ์˜ state ๊ด€๋ฆฌ ๋„๊ตฌ
  3. ํ†ต์‹  ๋ชจ๋“ˆ์˜ ์„ ํƒ
  4. ๋””์ž์ธ ํŒจํ„ด์˜ ๋„์ž…

ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด์ž!

HTML Rendering Server ์˜ ๊ฒฐ์ •

 

Front End๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ React๋กœ ํ•˜๋ ค๋˜ ์ƒ๊ฐ์€ ์—†์—ˆ๋‹ค.

 

์ฒ˜์Œ์—๋Š” ์ˆœ์ˆ˜ HTML๊ณผ Vanila Javascript ๋ฅผ ์ด์šฉํ•  ์ƒ๊ฐ์ด์—ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์—ฌ๋Ÿฌ ๊ธฐ์ˆ  ์กฐ์‚ฌ๋ฅผ ํ–ˆ์„ ๋•Œ, ๊ฐ„๋‹จํžˆ ๋“ค์—ˆ๋˜ ์ƒ๊ฐ์€ ๋ฐ”๋กœ Express.js๋ฅผ ์ด์šฉํ•ด static file render ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

Expressjs ๋Š” Template Engine ํ”„๋ ˆ์ž„์›Œํฌ์ด๊ธฐ ๋•Œ๋ฌธ์— html render server ๋กœ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ช‡ ๊ฐ€์ง€ ์ž‘์—…์„ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

์šฐ์„  app.js ์—์„œ express.static() ์„ ์ด์šฉํ•ด์„œ static ํŒŒ์ผ์„ ๋ Œ๋”ํ•˜๋„๋ก ๊ตฌ์„ฑํ–ˆ๋‹ค.

 

import express from "express";

import path from "path";
const __dirname = path.resolve();

const app = express();
const port = 3000;

const setRenderPage = (filename) => __dirname + "/views/" + filename;

app.use("/script", express.static("script"));
app.use("/static", express.static("static"));

app.get("/", (req, res) => {
  res.sendFile(setRenderPage("index.html"));
});

app.listen(port, () => {
  console.log("server started on " + port);
});

 

์ด ๋ฐฉ๋ฒ•์—๋Š” ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š”๋ฐ, ๋ฐ”๋กœ css, images, js ํŒŒ์ผ์„ ๊ฐ๊ฐ render ํ•  url ์„ ์—ด์–ด์ค˜์•ผ ํ–ˆ์—ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ <head> ํƒœ๊ทธ ๋‚ด๋ถ€์— url routing path ๋ฅผ ์ƒ๊ฐํ•˜๋ฉด์„œ static file ์„ ๋ฐ˜ํ™˜ํ–ˆ์ง€๋งŒ, ์ด๋Š” ์ƒ์‚ฐ์„ฑ์„ ์ €ํ•ด์‹œํ‚ค๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์˜€๋‹ค.

 

์ด๊ฑด ๊ทธ๋ž˜ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ๋ฐ, ๋ฌธ์ œ๋Š” ๋ฐ”๋กœ es6 ์—์„œ Module์„ Bundling ํ•˜๋Š”๋ฐ ์ •๋ง ํž˜๋“ค์—ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค๋ฉด es6 ์ด์ „์—๋Š” ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ, const express = require('express') ์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ์ด์šฉํ–ˆ์ง€๋งŒ es6 ์ด์ƒ์€ import express from 'express' ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋“ค ์‚ฌ์ด์˜ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ถˆ์ผ์น˜?๋ฅผ ํ•ด๊ฒฐํ–ˆ์–ด์•ผ ํ–ˆ๊ณ , ๊ฐ๊ฐ ๋”ฐ๋กœ ๋ฒˆ๋“ค๋ง์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ–ˆ๋‹ค.

 

์ „๋ฌธ Front ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ ๋‚˜์—๊ฒŒ๋Š” ์กฐ๊ธˆ ์–ด๋ ค์› ๋‹ค..

 

๊ทธ๋ž˜์„œ ์ƒ๊ฐํ•ด๋‚ธ ๋ฐฉ๋ฒ•์ด ๋ฐ”๋กœ Webpack ์ด์—ˆ๋‹ค.

 

 

์›นํŒฉ์€ ๋ชจ๋˜ js๋ฅผ ์œ„ํ•œ static ๋ชจ๋“ˆ bundler ๋ผ๊ณ  ํ•œ๋‹ค.

 

๊ฐ„๋‹จํ•˜๊ฒŒ ์›นํŒฉ์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•˜์ž๋ฉด, main.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ํ•˜๋‚˜์˜ main.js ์— ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๋‹ค์–‘ํ•œ ๋ชจ๋“ˆ๋“ค์„ ๋„ฃ๊ณ  main.js ํ•˜๋‚˜๋งŒ url ๋กœ ๊ฐœ๋ฐฉํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋น„์Šทํ•œ๊ฒƒ ๊ฐ™์•˜๋‹ค.

 

๊ทธ๋ž˜์„œ ์•ž์„œ ๋ฐœ์ƒํ–ˆ๋˜ ๋ฌธ์ œ๋“ค์€ ๋” ๊น”๋”ํ•˜๊ณ  ํ˜„๋Œ€์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

์‚ฌ์‹ค ๋ฆฌ์•กํŠธ๋„ ์›นํŒฉ์„ ์ด์šฉํ•˜๊ณ  ์žˆ๊ณ  ๋‚˜๋„ ์›นํŒฉ์— ๋Œ€ํ•œ ์–ธ๊ธ‰์€ ๋“ค์–ด๋ดค์ง€๋งŒ ๊นŠ๊ฒŒ ๊ณต๋ถ€ํ•ด๋ณธ ์ ์ด ์—†์—ˆ๋Š”๋ฐ, ์ด์ œ ์›นํŒฉ์ด ๋ฌด์—‡์„ ํ•˜๋Š” ๊ธฐ์ˆ ์ธ๊ฐ€? ์— ๋Œ€ํ•œ ๋‹ต์„ ์–ด๋А์ •๋„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด์„œ ๋งค์šฐ ์‹ ๋‚ฌ์—ˆ๋‹ค ใ…Žใ…Ž..

 

์ž์„ธํ•œ ์‚ฌํ•ญ์€ ๊ธฐ์ˆ  ๊ณ ๋ฏผ์„ ์ •๋ฆฌํ•œ github์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค -> Webpack ์œผ๋กœ Front-Server ๊ตฌ์„ฑํ•˜๊ธฐ

ํ•˜์ง€๋งŒ ์ด ๋งˆ์ €๋„ ์™„๋ฒฝํ•œ ๊ธฐ์ˆ  ์„ ์ •์€ ์•„๋‹ˆ์—ˆ๋‹ค.

 

๋‚˜๋Š” Vanila js ๋กœ ํ•˜๋‚˜์˜ ์›น์„ ๊ฐœ๋ฐœํ•ด๋ณธ ๊ฒฝํ—˜์ด ์—†์—ˆ๊ธฐ์— ๋งŒ์•ฝ ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ ํŒ€์›์ด ๋„์›€์„ ์š”์ฒญํ•  ๋•Œ, ํฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์—†์„๊ฒƒ ๊ฐ™์•˜๋‹ค.

 

๋ฆฌ์•กํŠธ์—์„œ๋Š” data fetching ์„ ํ•˜๋ฉด state๋ฅผ ๋ฐ”๊ฟ”์ฃผ์–ด ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ–ˆ์ง€๋งŒ, ๋ฐ”๋‹๋ผ js ์—์„œ๋Š” ์ง์ ‘ document ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ dom ์„ ์กฐ์ž‘ํ•ด์•ผ ํ–ˆ๊ณ , ajax ํ†ต์‹ ์—์„œ๋„ ์–ด๋–ป๊ฒŒ ๋ Œ๋”๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š”์ง€ ํ™•์‹คํ•œ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ–ˆ์—ˆ๋‹ค.

 

๊ฐ„๋‹จํžˆ ๊ฒŒ์‹œํŒ ์ •๋„๋Š” ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋จธ๋ฆฌ์†์œผ๋กœ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ๊ฒ ๋‹ค! ์‹ถ์ง€๋งŒ ๋ง‰์ƒ ๊ทœ๋ชจ๊ฐ€ ์žˆ๋Š” ์•ฑ์„ ๊ฐœ๋ฐœํ•  ๋•Œ, ๋ฐœ์ƒํ•  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ž์‹ ๊ฐ์ด ๋ถ€์กฑํ–ˆ๋‹ค.

 

์ •๋ง ๋‹คํ–‰์ธ ๊ฒƒ์€ ํ”„๋ก ํŠธ๋ฅผ ๋งก์€ ํŒ€์›์ด ๋ฆฌ์•กํŠธ ๊ฒฝํ—˜์ด ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ ๋ฆฌ์•กํŠธ๋กœ ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป๊ฒ ๋ƒ๋Š” ์˜๊ฒฌ์„ ๋‚ด์—ˆ๊ณ , ๊ธ์ •์ ์œผ๋กœ ๋ฐ›์•„๋“ค์—ฌ์ค˜์„œ ์šฐ๋ฆฌ๋Š” ํ”„๋ก ํŠธ๋ฅผ ๋ฆฌ์•กํŠธ๋กœ ๊ตฌ์„ฑํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

 

๊ฒฐ๊ตญ ํŒ€์›๋“ค์˜ ์–‘ํ•ด๋ฅผ ๊ตฌํ•ด ๋ฆฌ์•กํŠธ๋กœ ๋ณ€๊ฒฝ!

 

์ง€๋‚œ ๋‚ด ๊ฒฝํ—˜์—์„œ๋Š” ์ง์ ‘ Design๊ณผ Style ๊ฐœ๋ฐœ์„ ํ–ˆ์—ˆ์ง€๋งŒ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Backend ์—์„œ ํ•ด์•ผํ•  ์ผ๋“ค์ด ์กฐ๊ธˆ ์žˆ์—ˆ๊ณ , ๋‚ด๊ฐ€ ์ธํ”„๋ผ๊นŒ์ง€ ๊ตฌ์„ฑ์„ ํ–ˆ์–ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋””์ž์ธ ์ชฝ์€ ์•„์˜ˆ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.

 

๋˜ํ•œ UI๋ฅผ ์ „๋ฌธ์ ์œผ๋กœ ๊ณต๋ถ€ํ–ˆ๋˜ ํŒ€์›๋“ค์ด ์—†์—ˆ๊ธฐ์— React Bootstrap์„ ์ด์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

 

๋‚˜๋Š” Bootstrap ์„ ํ•œ ๋ฒˆ๋„ ์‚ฌ์šฉํ•ด๋ณธ ์ ์ด ์—†์—ˆ๊ธฐ์— ํ”„๋ก ํŠธ๋ฅผ ๋งก์€ ํŒ€์›์ด Bootstrap ์„ ๋งŒ์ ธ๋ณด๋ฉฐ ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ Chart ๋“ค๊ณผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋”ฐ๋กœ ๋นผ์„œ ๋ชจ๋“ˆํ™”๋ฅผ ํ•ด ์ฃผ์—ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ์ ํŠธ Repository ์—์„œ create-react-app ์„ ์ด์šฉํ•ด์„œ ๊ธฐ๋ณธ Building ์„ ํ•˜๊ณ , ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉ์„ ํ–ˆ์—ˆ๋‹ค.

 

๋ฆฌ์•กํŠธ์˜ state ๊ด€๋ฆฌ ๋„๊ตฌ

 

React ์˜ ํฐ ํŠน์ง• ๋‘ ๊ฐ€์ง€๋ฅผ ์ด์•ผ๊ธฐ ํ•˜์ž๋ฉด ๋ฐ”๋กœ State์™€ Props ์ด๋‹ค.

 

Props์™€ State๋Š” ์ผ๋ฐ˜ Js ๊ฐ์ฒด๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ์˜ ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

state๋Š” ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜ํ˜• ๋ฐ์ดํ„ฐ์ธ๋ฐ, ํ•ด๋‹น state๋ฅผ ์ด์šฉํ•ด์„œ ๋™์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ UI์— ์‚ฝ์ž…ํ•ด์„œ ๋ Œ๋”๋งํ•œ๋‹ค.

 

์ด ๊ณผ์ •์—์„œ state๋Š” ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์œ„์น˜ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ์ž˜ ์ƒ๊ฐํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

 

์ด๋Ÿฐ ํŠน์„ฑ์„ ์ž˜๋ชป ์ด์šฉํ•œ๋‹ค๋ฉด ์›ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ์ž˜ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋ž€ ์กฐ๊ธˆ ๊นŒ๋‹ค๋กญ๋‹ค.

 

๊ทธ๋ž˜์„œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋‹ค์–‘ํ•œ ์„ ํƒ์ง€๊ฐ€ ์žˆ์—ˆ๋‹ค.

 

  1. ์ˆœ์ˆ˜ State + Props ์ด์šฉํ•˜๊ธฐ
  2. ์ „์—ญ State ๊ด€๋ฆฌ ๋„๊ตฌ ์ด์šฉํ•˜๊ธฐ (Mobx, Context API, Redux)

 

์ˆœ์ˆ˜ State + Props ์ด์šฉํ•˜๊ธฐ

 

์ˆœ์ˆ˜ state๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ ๋ Œ๋” ํŠธ๋ฆฌ์˜ ๊ตฌ์กฐ๋ฅผ ์ž˜ ํŒŒ์•…ํ•˜๊ณ  ์ ์ ˆํžˆ props๋กœ ๋‚ด๋ ค์ค˜์•ผ ํ•œ๋‹ค.

 

๊ทธ๋ž˜์„œ ์ฝ”๋“œ๊ฐ€ ์ž์นซ ์ž˜๋ชปํ•˜๋ฉด ์ข€ ๋”๋Ÿฌ์›Œ์ง€๊ฑฐ๋‚˜ ๊ฐ€๋…์„ฑ์ด ๋‚˜๋น ์ง„๋‹ค.

 

์ „์—ญ state ๊ด€๋ฆฌ ๋„๊ตฌ ์ด์šฉํ•˜๊ธฐ

 

ํ˜„์žฌ ๊ฐœ์ธ์ ์ธ ํ”„๋กœ์ ํŠธ์—์„œ ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ redux์™€ redux-thunk ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

 

ํ™•์‹คํžˆ ์ˆœ์ˆ˜ state์™€ props ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ณด๋‹ค ๋‹ค์–‘ํ•˜๊ณ  ๋” ์‰ฌ์šด ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•˜๊ธฐ ๊นŒ์ง€ ์กฐ๊ธˆ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฉฐ, ๋ฌด์—‡๋ณด๋‹ค ์ด ์ƒ๊ฐ์ด ์•ž์„ฐ๋‹ค.

 

๊ณผ์—ฐ ์šฐ๋ฆฌ ์„œ๋น„์Šค์—์„œ Redux๊ฐ€ ํ•„์š”ํ• ๊นŒ??

 

์ •๋‹ต์€ No ์ด๋‹ค.

 

์‚ฌ์‹ค ๋™์  Data Fetching ๋„ ์—†๊ณ  ๋‹จ์ง€ ์ปดํฌ๋„ŒํŠธ์˜ Depth ๋„ ๊นŠ์–ด๋ดค์ž 5๊ฐœ? ์ •๋„์˜€๋‹ค.

 

๊ทธ๋ž˜์„œ Redux๋Š” ๊ณผ๊น€ํžˆ Pass ํ•˜๊ณ  ์ˆœ์ˆ˜ state์™€ props์™€ useState ํ›…์„ ์ฃผ๋กœ ์ด์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

 

ํ†ต์‹  ๋ชจ๋“ˆ์˜ ์„ ํƒ

 

๋ธŒ๋ผ์šฐ์ €์—์„œ Ajax ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‚ด๊ฐ€ ์‚ฌ์šฉํ–ˆ๋˜ ํ†ต์‹  ๋ชจ๋“ˆ์€ 2๊ฐ€์ง€ ์ด๋‹ค.

 

  1. Fetch API
  2. Axios

 

๋‘˜ ๋‹ค Ajax ์˜ Request ๋ฅผ ์ถ”์ƒํ™”ํ•œ ๋ชจ๋“ˆ๋กœ ๊ฐœ์ธ์ ์œผ๋กœ Axios๋ฅผ ๋” ๋งŽ์ด ์„ ํ˜ธํ•œ๋‹ค.

 

๊ทธ ์ด์œ ๋Š” ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ,

 

  1. Promise ์ฒ˜๋ฆฌ๊ฐ€ ์‰ฝ๋‹ค
  2. ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•˜๋‹ค
  3. json ์ฒ˜๋ฆฌ๊ฐ€ ๋” ์‰ฝ๋‹ค
  4. ๊ฒฝํ—˜์ด ๋” ๋งŽ๋‹ค ใ…Žใ…Ž

 

 

๊ฒฐ๊ตญ Axios ๋ฅผ ์ด์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด API ๋ชจ๋“ˆ์„ ๊ตฌ์„ฑํ–ˆ๋‹ค.

 

import axios from "axios";

export const SERVER = axios.create({
  baseURL: "http://" + process.env.REACT_APP_HOST_IP,
  headers: {
    "Content-Type": "application/json",
  },
});

export const TEST_SERVER = axios.create({
  baseURL: "http://localhost:8080/api",
  headers: {
    "Content-Type": "application/json",
  },
});

 

SERVER.js ๋ผ๋Š” ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์œ„์™€ ๊ฐ™์ด ์„œ๋ฒ„์˜ ํ˜ธ์ถœ ip๋ฅผ ๋„ฃ์–ด์„œ axios instance ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๊ฐ๊ฐ์˜ ๊ด€์‹ฌ์‚ฌ์— ๋งž๊ฒŒ ๋ฏผ๋“  Service.js ํŒŒ์ผ์—์„œ axios instance ๋ฅผ import ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

import { SERVER, TEST_SERVER } from "util/SERVER";

export const fetchAllLog = async () => {
  const { data } = await SERVER.get("/api/logs/all");

  return data;
};

export const fetchUnknownLog = async () => {
  const { data } = await SERVER.get("/api/logs/unknown");

  return data;
};

 

๋””์ž์ธ ํŒจํ„ด์˜ ๋„์ž…

 

๋‚˜๋Š” ๋””์ž์ธ ํŒจํ„ด์€ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์— ์žˆ์–ด์„œ ๋งค์šฐ๋งค์šฐ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์‚ฌ๋žŒ์ด๋‹ค

 

๊ทธ๋ž˜์„œ ๊ฐ„๋‹จํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ๊ฐ€์žฅ ๋จผ์ € ๋””์ž์ธ ํŒจํ„ด์„ ๊ณ ๋ฏผํ–ˆ์—ˆ๋‹ค.

 

๋‚ด๊ฐ€ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒฝํ—˜ํ–ˆ๋˜ ๋””์ž์ธ ํŒจํ„ด์€ ํฌ๊ฒŒ 2๊ฐ€์ง€์˜€๋‹ค.

 

  1. Container-Presenter Pattern
  2. Atomic Design Pattern

 

Atomic Design Pattern ์€ ์›์†Œ๊ฐ€ ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์— ํŠนํ™”๋˜์–ด ์žˆ๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ์‚ฌ์‹ค์ƒ Single Page ๋กœ ์šด์˜๋˜๊ณ  Routing ์กฐ์ฐจ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ตญ Container-Presenter Pattern ์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

 

์•ž์„œ ์ด์•ผ๊ธฐํ–ˆ๋˜ ํ†ต์‹  ๋ชจ๋“ˆ๊ณผ Service ๋ฅผ Container ์—์„œ ๋ฐ›์•„์™€ ๊ทธ ์•„๋ž˜์˜ Presenter ๋“ค์—๊ฒŒ Props ๋กœ ์ „๋‹ฌํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค.

 

 

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์‹ค์ œ Log ๋ฅผ ํ…Œ์ด๋ธ” ํ˜•์‹์œผ๋กœ ๋ Œ๋”ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์—์„œ ์‚ฌ์šฉํ•˜๋Š” Container ์ฝ”๋“œ์ด๋‹ค.

 

import React, { useEffect, useState } from "react";

import LogTable from "components/presenter/LogTable/index";

import { fetchAllLog } from "service/LogService";
const LogTableContainer = () => {
  const [logDatas, setLogDatas] = useState([]);

  useEffect(async () => {
    const data = await fetchAllLog();
    setLogDatas(data);
  }, []);

  return <LogTable logDatas={logDatas} />;
};

export default LogTableContainer;

 

๋จผ์ € ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋กœ๋“œ๋˜๋Š” ์ˆœ๊ฐ„ API ํ˜ธ์ถœ์„ ์‹œ๋„ํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  useEffect ๋‚ด๋ถ€์—์„œ data fetching ์„ ํ•œ๋‹ค.

 

๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ <LogTable> ์˜ props ๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ ์ ˆํžˆ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ๋‚ด๋ ค์ฃผ๋ฉด์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ UI๋ฅผ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋œ๋‹ค.

 

 

์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ Front End React Application ์€ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

 

 

์‚ฌ์‹ค ์ด ๊ตฌ์กฐ๊ฐ€, ํ”„๋ก ํŠธ๋ฅผ ๋ฆฌ์•กํŠธ๋กœ ์„ ์ •ํ•œ ์ด์œ  ์กฐ์ฐจ๊ฐ€ ํƒ€๋‹นํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

 

๋˜ํ•œ ๊ธฐ์ˆ  ์ž์ฒด์˜ ์‚ฌ์šฉ๋ฒ•๋„ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋‚˜๋ฆ„ 1๋‹ฌ์ด๋ผ๋Š” ์งง์€ ๊ธฐ๊ฐ„๋™์•ˆ ์œ ์šฉํ•˜๊ณ  ๊ฝค๋‚˜ ๊ตฌ์กฐ์ ์œผ๋กœ ์ž˜ ๊ตฌ์„ฑํ•˜์—ฌ ํ˜‘์—…์„ ์ง„ํ–‰ํ–ˆ์—ˆ๋‹ค.

 

ํ”„๋ก ํŠธ์—”๋“œ๋Š” ๋‹จ์ˆœํžˆ ์ทจ๋ฏธ ์ฏค์œผ๋กœ ์ƒ๊ฐํ–ˆ๋˜ ์ง€๋‚œ์˜ ๊ฒฝํ—˜๋“ค์ด ์ด๋ ‡๊ฒŒ ๋น›์„ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ๋ฟŒ๋“ฏํ–ˆ๊ณ , ๋‚˜๋ฆ„ ์ž๋ž‘์Šค๋Ÿฌ์› ๋”ฐ ใ…Žใ…Ž.

 

๋‹ค์Œ ์‹œ๊ฐ„์€ ๋ฐฑ์—”๋“œ์˜ Spring Boot ์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•ด๋ณด๋ ค ํ•œ๋‹ค!