Skip to content

๐Ÿ’ก ์„œ๋น„์Šค ์†Œ๊ฐœ ๋ฐ ๊ธฐ์ˆ  ์Šคํƒ

๐ŸŽฏ ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

์นตํ…Œ์ผ ์ฃผ๋ฅ˜ ์ •๋ณด API๋Š” ์นตํ…Œ์ผ ์ œ์กฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋”์šฑ ํšจ์œจ์ ์ด๊ณ  ์ฐฝ์˜์ ์œผ๋กœ ๋งŒ๋“ค๊ณ ์ž ํ•˜๋Š” ์—ด์ •์—์„œ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋ฅ˜(Spirits), ๋ฆฌํ๋ฅด(Liqueurs), ๊ทธ๋ฆฌ๊ณ  ๋‹ค์–‘ํ•œ ๋ณด์กฐ ์žฌ๋ฃŒ(Ingredients)์˜ ๋ณต์žกํ•œ ํŠน์„ฑ๋“ค์„ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•˜๊ณ , ํ•„์š”ํ•  ๋•Œ ์ฆ‰์‹œ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์นตํ…Œ์ผ ์ œ์กฐ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฌ๊ณ ํ•˜๊ณ  ์œ ์—ฐํ•œ RESTful API ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ด ํ”„๋กœ์ ํŠธ์˜ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

์ด๋Š” ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์„ ๋„˜์–ด, ๊ฐ ์žฌ๋ฃŒ๋ณ„ ๊ณ ์œ ์˜ ํ–ฅ(Aroma), ๋ง›(Taste), ์—ฌ์šด(Finish)๊ณผ ๊ฐ™์€ ๊ฐ๊ฐ์ ์ธ ์ •๋ณด๊นŒ์ง€ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ์ตœ์ ์˜ ์žฌ๋ฃŒ๋ฅผ ์„ ํƒํ•˜๊ณ  ์ƒˆ๋กœ์šด ์นตํ…Œ์ผ ์กฐํ•ฉ์„ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ๊ธฐ์ˆ  ์Šคํƒ (Technical Stack)

์ด ์„œ๋น„์Šค๋Š” ํ˜„๋Œ€์ ์ธ ์›น ๊ธฐ์ˆ ๊ณผ ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ์ˆ  ์Šคํƒ์„ ํ™œ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์—”๋“œ (Backend)

  • ์ฃผ์š” ์–ธ์–ด ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ: Python 3.13 & FastAPI
  • ๋†’์€ ์„ฑ๋Šฅ๊ณผ ๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„๋ฅผ ์ž๋ž‘ํ•˜๋Š” FastAPI๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ RESTful API๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค
  • uvloop ์ด๋ฒคํŠธ ๋ฃจํ”„ ์ •์ฑ…์œผ๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค
  • ORJSON์„ ์‚ฌ์šฉํ•œ ๊ณ ์„ฑ๋Šฅ JSON ์ง๋ ฌํ™”
  • Pydantic์„ ํ†ตํ•œ ํƒ€์ž… ์•ˆ์ „ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ

  • ์ข…์†์„ฑ ๊ด€๋ฆฌ: UV

  • Rust ๊ธฐ๋ฐ˜์˜ ๊ณ ์„ฑ๋Šฅ Python ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž
  • ๊ธฐ์กด pip/poetry ๋Œ€๋น„ 10-100๋ฐฐ ๋น ๋ฅธ ์„ค์น˜ ์†๋„

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (Database)

  • MongoDB: ์ฃผ๋ฅ˜์˜ ๋ณต์žกํ•˜๊ณ  ์œ ๋™์ ์ธ ํŠน์„ฑ(ํ–ฅ, ๋ง›, ์—ฌ์šด ๋“ฑ)๊ณผ ์ด๋ฏธ์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์œ ์—ฐํ•œ NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค
  • SQLite: ๋ง›, ํ–ฅ, ์›์‚ฐ์ง€ ๋“ฑ ์ •ํ˜•ํ™”๋œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๊ฒฝ๋Ÿ‰ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค

์ธ์ฆ ๋ฐ ๋ณด์•ˆ (Authentication & Security)

  • SuperTokens: ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์„ธ์…˜ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์˜คํ”ˆ์†Œ์Šค ์†”๋ฃจ์…˜
  • ์ด๋ฉ”์ผ/ํŒจ์Šค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ธ์ฆ
  • ์„ธ์…˜ ๊ด€๋ฆฌ ๋ฐ ํ† ํฐ ๊ฐฑ์‹ 
  • JWT (JSON Web Token): ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด (RBAC)
  • ๋ณด์•ˆ ๋ฏธ๋“ค์›จ์–ด:
  • CORS ์„ค์ •
  • ์••์ถ• ๋ฏธ๋“ค์›จ์–ด (Brotli/Gzip)
  • TrustedHost ๋ฏธ๋“ค์›จ์–ด

ํ”„๋ก ํŠธ์—”๋“œ (Frontend)

  • React 19: ์ตœ์‹  React ๋ฒ„์ „์œผ๋กœ ๋ชจ๋˜ UI ๊ตฌํ˜„
  • TypeScript: ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์œ„ํ•œ ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ
  • Vite: ๊ณ ์„ฑ๋Šฅ ๋นŒ๋“œ ๋„๊ตฌ ๋ฐ ๊ฐœ๋ฐœ ์„œ๋ฒ„
  • TailwindCSS v4: ์œ ํ‹ธ๋ฆฌํ‹ฐ ์šฐ์„  CSS ํ”„๋ ˆ์ž„์›Œํฌ
  • PNPM: ๊ณ ์„ฑ๋Šฅ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €

์ฝ”๋“œ ํ’ˆ์งˆ (Code Quality)

  • Python ๋„๊ตฌ:
  • Ruff: ๊ณ ์„ฑ๋Šฅ ๋ฆฐํ„ฐ ๋ฐ ํฌ๋งคํ„ฐ (Rust ๊ธฐ๋ฐ˜)
  • Pyright: TypeScript ๊ธฐ๋ฐ˜ ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ๊ธฐ
  • pytest: ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ
  • JavaScript/TypeScript ๋„๊ตฌ:
  • Biome: ํ†ตํ•ฉ ๋ฆฐํ„ฐ ๋ฐ ํฌ๋งคํ„ฐ (Rust ๊ธฐ๋ฐ˜)
  • Vitest: ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ

๋ฌธ์„œํ™” (Documentation)

  • MkDocs: Material ํ…Œ๋งˆ๋ฅผ ์‚ฌ์šฉํ•œ ์ •์  ๋ฌธ์„œ ์‚ฌ์ดํŠธ ์ƒ์„ฑ
  • mkdocstrings: Python ๋…์ŠคํŠธ๋ง ์ž๋™ ํŒŒ์‹ฑ ๋ฐ API ๋ฌธ์„œ ์ƒ์„ฑ

๊ฐœ๋ฐœ ๋„๊ตฌ (Development Tools)

  • Docker: ์ปจํ…Œ์ด๋„ˆํ™”๋œ ๊ฐœ๋ฐœ ๋ฐ ๋ฐฐํฌ ํ™˜๊ฒฝ
  • Pre-commit: Git ์ปค๋ฐ‹ ์ „ ์ž๋™ ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์‚ฌ
  • Structlog: ๊ตฌ์กฐํ™”๋œ ๋กœ๊น…
  • Pyinstrument: ์„ฑ๋Šฅ ํ”„๋กœํŒŒ์ผ๋ง

์„ฑ๋Šฅ ์ตœ์ ํ™” (Performance)

  • uvloop: ๊ณ ์„ฑ๋Šฅ ์ด๋ฒคํŠธ ๋ฃจํ”„
  • ORJSON: ๊ณ ์„ฑ๋Šฅ JSON ์ง๋ ฌํ™”
  • Compression: Brotli/Gzip ์‘๋‹ต ์••์ถ•
  • Async/Await: ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋กœ ๋†’์€ ๋™์‹œ์„ฑ ์ง€์›

๐Ÿค ๊ธฐ์—ฌ ๋ฐ ํ”ผ๋“œ๋ฐฑ

์ด ํ”„๋กœ์ ํŠธ๋Š” ์ง€์†์ ์œผ๋กœ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ํ˜•ํƒœ์˜ ๊ธฐ์—ฌ๋‚˜ ํ”ผ๋“œ๋ฐฑ๋„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„๊ทธ ๋ณด๊ณ , ๊ธฐ๋Šฅ ์ œ์•ˆ ๋˜๋Š” ์ฝ”๋“œ ๊ธฐ์—ฌ๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ ๋ฐœ์ „์— ์ฐธ์—ฌํ•ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.