Skip to content

๐Ÿ  ์ฃผ๋ง๋‚ด์ง‘, ๋“€์–ผ ๋ผ์ดํ”„ ์ปค๋ฎค๋‹ˆํ‹ฐ ๐Ÿ 

Notifications You must be signed in to change notification settings

ODOICHON/server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

์ฃผ๋ง๋‚ด์ง‘ - ๋“€์–ผ ๋ผ์ดํ”„ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋žซํผ ๐Ÿ 

Quality Gate Status Coverage Code Smells Bugs CD Hits

ํ”„๋กœ์ ํŠธ ์„ค๋ช…

"์ฃผ๋ง๋‚ด์ง‘"์€ ๋“€์–ผ ๋ผ์ดํ”„๋ฅผ ๊ฟˆ๊พธ๊ณ  ์‹คํ˜„ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค ๊ฐ„์˜ ์†Œํ†ต์˜ ๊ณต๊ฐ„ ๋ถ€์กฑ๊ณผ ์ง€์—ญ ์‚ฌํšŒ์˜ ๋นˆ์ง‘ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

๋ณธ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฝํ—˜๊ณผ ์ง€์‹์„ ์Œ“๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • SpringBoot ์™€ Kotlin ๊ธฐ๋ฐ˜์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์•  ์ฃผ๊ธฐ ๊ธฐํš๋ถ€ํ„ฐ ๋ฐฐํฌ ๋ฐ ์šด์˜๊นŒ์ง€ ๊ฒฝํ—˜
  • AWS ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ ๊ธฐ๋ฐ˜์˜ CICD ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ์ธํ”„๋ผ ๊ตฌ์ถ• ๊ฒฝํ—˜
  • JPA, Hibernate๋ฅผ ์‚ฌ์šฉํ•œ ๋„๋ฉ”์ธ ์„ค๊ณ„ ๊ฒฝํ—˜
  • MVC ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„ ๊ตฌ์ถ•
  • SSR ๋ฐฉ์‹์˜ ๋ฐฑ์˜คํ”ผ์Šค ๊ฐœ๋ฐœ ๊ฒฝํ—˜
  • ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ ์šฉ๋œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๊ตฌํ˜„ ๊ฒฝํ—˜
  • ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•œ ๊ณ ๋ฏผ๊ณผ ๋„์ „ ๊ฒฝํ—˜
  • Unit Test ์ฝ”๋“œ ์ž‘์„ฑ์„ ํ†ตํ•œ ์•ˆ์ •์„ฑ ํ™•๋ณด ( 23๋…„๋„ 9์›” ๊ธฐ์ค€ 151๊ฐœ์˜ Unit Test ์ฝ”๋“œ ์ž‘์„ฑ )

๊ธฐ์ˆ  ์Šคํƒ

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ( Language & Framework & Library )

  • Kotlin
  • Spring Framework ( Spring Boot 2.7.8, Spring MVC )
  • Spring Data JPA, Redis, QueryDsl
  • Junit5, AssertJ, Mockito
  • Rest Docs

Build Tool

  • Gradle( Kotlin )

Database

  • MySQL
  • Redis

์ธํ”„๋ผ( with CICD )

แ„†แ…ตแ†บแ„‹แ…ฅแ†ธแ„ƒแ…ฆแ„‹แ…ต-แ„‹แ…กแ„แ…ตแ„แ…ฆแ†จแ„Žแ…ฅ-cicd-flow drawio

  • AWS Route 53
  • AWS EC2
  • Nginx, AWS S3, AWS CodeDeploy(Agent)
  • AWS RDS
  • Git, Github Actions
  • CloudWatch, Slack
  • Jacoco, SonarCloud
  • Docker
  • Lambda

WEB for back-office

  • Javascript
  • HTML/CSS
  • Thymeleaf
  • Bootstrap 5

WEB for tech-blog

  • Typescript
  • HTML/CSS
  • Vue3
  • Vuex
  • Vue-Router
  • Bootstrap 5
  • Axios
  • npm
  • Toast-ui for vue

๊ทธ์™ธ ์ฃผ์š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • JWT
  • Bucket4j
  • Cache
  • Coolsms
  • Jasypt

E-R ๋‹ค์ด์–ด๊ทธ๋žจ

แ„Œแ…ฎแ„†แ…กแ†ฏแ„‚แ…ขแ„Œแ…ตแ†ธ ERD-7

REST DOCS ๊ธฐ๋ฐ˜ API ๋ช…์„ธ์„œ

์ „์ฒด ๋ฌธ์„œ

์ฃผ๋ง๋‚ด์ง‘ ์„œ๋น„์Šค

ํ…Œํฌ๋ธ”๋กœ๊ทธ ์„œ๋น„์Šค

๊ณตํ†ต ๋ฌธ์„œ


ํ•ต์‹ฌ ๊ธฐ๋Šฅ ( with ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… )

๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ์œผ๋กœ ์ธํ•œ swap์œผ๋กœ ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ ์„ค์ •

ํ”„๋ฆฌํ‹ฐ์–ด ํ™˜๊ฒฝ์—์„œ EC2 ์„œ๋ฒ„๋ฅผ ์šด์˜ํ•˜๋ฉด์„œ CD๋ฅผ ํ†ตํ•ด ๋ฐฐํฌํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ์ฃฝ๋Š” ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. swap์„ ํ†ตํ•ด ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ ์„ค์ •์„ ํ†ตํ•ด ํ•ด๋‹น ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ์ฆ์„คํ•˜๋Š” ๊ฒƒ ๋Œ€์‹  ๊ฐ€์šฉ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋Š˜๋ฆฐ ์ด์œ ๋Š” ๋น„์šฉ ๋ฐœ์ƒ ๊ตฌ๊ฐ„์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ์œ„ํ•œ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ

ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ๊ด€๋ จ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์ดํ›„, ๋ฐฐํฌ๋œ ์‚ฌ์ดํŠธ๋ฅผ ํ†ตํ•ด QA๋ฅผ ํ•˜๋ฉด์„œ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ์— ๋Œ€ํ•œ ๊ฑฑ์ •์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘์†ํ•ด์„œ ํšŒ์›๊ฐ€์ž… ๊ณผ์ •์„ ๊ฑฐ์ณ ์‚ฌ์ดํŠธ์— ์ œ๊ณตํ•˜๋Š” ์ •๋ณด์— ๋Œ€ํ•ด ์ œ3์ž๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๋Š” ๊ฒƒ์€ ๋‹น์—ฐํ•˜์ง€๋งŒ, ์ด๋ฅผ ์šด์˜ํ•˜๋Š” ๊ด€๋ฆฌ์ž๋“ค๋กœ๋ถ€ํ„ฐ๋„ ๋ณดํ˜ธ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ƒ์„ฑ/์ˆ˜์ •/์กฐํšŒ ์‹œ, ์•”ํ˜ธํ™”์™€ ๋ณตํ˜ธํ™” ์ฒ˜๋ฆฌ๋ฅผ ๊ฑฐ์น˜๋„๋ก ๋ฆฌํŽ™ํ† ๋งํ•˜์˜€์Šต๋‹ˆ๋‹ค. DB์— ์ฝ˜์†”๋กœ ์ ‘๊ทผํ•˜์—ฌ select ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ์กฐํšŒํ•˜๋”๋ผ๋„ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋Š” ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ๋œ ์ƒํƒœ๋กœ ์กฐํšŒ๋ฉ๋‹ˆ๋‹ค. ์•”๋ณตํ˜ธํ™”๋Š” Converter์™€ AES ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฆฌํŽ™ํ† ๋ง ๊ณผ์ •์€ ์œ ์ € ํ…Œ์ด๋ธ” ์•”ํ˜ธํ™”์—์„œ ์ž์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ํƒˆํ‡ด ์ดํ›„์˜ ์ฒ˜๋ฆฌ

์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์–ป๋Š” ๋ฐ์ดํ„ฐ๋กœ ์šด์˜๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ํƒˆํ‡ด๋ฅผ ํ•˜๋”๋ผ๋„ ๊ฐœ์ธ์ •๋ณด๋ฅผ ์ œ์™ธํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋ณด์œ ํ•˜๊ณ  ์žˆ๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ delete ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ "" ๊ณต๋ฐฑ ๋ฌธ์ž๋ฅผ ๋„ฃ์–ด ์‚ฌ์šฉ์ž ํ…Œ์ด๋ธ”๊ณผ Cascade๊ฐ€ ๊ฑธ๋ฆฐ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์กดํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฆฌํŽ™ํ† ๋งํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฆฌํŽ™ํ† ๋ง ๊ณผ์ •์€ ์œ ์ € ํƒˆํ‡ด ์ฒ˜๋ฆฌ์—์„œ ์ž์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์ €์žฅ๋ฐฉ์‹์˜ ๋ณ€๊ฒฝ

๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์ค‘์— JWT ํ† ํฐ ํ˜•ํƒœ์˜ Access-token๊ณผ Refresh-token์„ Frontend์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ localstorage์— ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. Server์—์„œ๋Š” Redis ์„œ๋ฒ„์— Refresh-token์„ ์ €์žฅํ•˜์—ฌ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ ํšจ๊ธฐ๊ฐ„์ด ๊ธด Refresh-token์ด localstorage์— ์ €์žฅ๋˜๋ฉด XSS ๊ณต๊ฒฉ ๋“ฑ์œผ๋กœ ํƒˆ์ทจ ๋‹นํ•  ์œ„ํ—˜์ด ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ Cookie์— ๋‹ด์•„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฆฌํŽ™ํ† ๋ง ๊ณผ์ •์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์ €์žฅ๋ฐฉ์‹ ๋ณ€๊ฒฝ์—์„œ ์ž์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…Œํฌ ๋ธ”๋กœ๊ทธ ์„œ๋น„์Šค ๊ธฐํš/๊ฐœ๋ฐœ

ํŒ€ ์˜ค๋„๋ฆฌ์—์„œ ์ฃผ๋ง๋‚ด์ง‘ ์„œ๋น„์Šค ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ๊ฑฐ์ณ์˜จ ์ง€๋‚œ ์—ฌ์ •๊ณผ ๋งˆ์ฃผํ–ˆ๋˜ ์ด์Šˆ ๋ฐ ํšŒ๊ณ ์— ๋Œ€ํ•ด ์‚ฌ์šฉ์ž๋“ค๊ณผ ๊ณต์œ ํ•˜๊ณ ์ž off the record๋กœ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ํ•ด๋‹น ์„œ๋น„์Šค๋Š” ์„œ๋ฒ„ ํŒŒํŠธ ๋‚ด๋ถ€์—์„œ ์ž์ฒด์ ์œผ๋กœ ๊ธฐํš/๋””์ž์ธ/๊ฐœ๋ฐœ ํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ๋ณธ ์„œ๋น„์Šค์™€ ๊ณต์šฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” API๊ฐ€ ์žˆ๊ธฐ์— ํ•ด๋‹น ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ ์ถ”๊ฐ€ ํ™•์žฅ์œผ๋กœ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ ์ž‘์—… ๋‚ด์šฉ์€ back-office ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…Œํฌ ๋ธ”๋กœ๊ทธ ๋ฐ”๋กœ๊ฐ€๊ธฐ ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘‰๐Ÿป ํ…Œํฌ ๋ธ”๋กœ๊ทธ ํ”„๋กœ์„ธ์Šค ์ •์˜

๋กœ๊ทธ์ธ

image

๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ

image

๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •

image

๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

image

๊ฒŒ์‹œ๊ธ€ ๋Œ“๊ธ€ ์ž‘์„ฑ

image

๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ๋ทฐ ์กฐํšŒ

image

๋งˆ์ดํŽ˜์ด์ง€ ๋ฆฌ๋ทฐ ๋“ฑ๋ก

image

์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ์—์„œ ํŽ˜์ด์ง• ๋ฐ์ดํ„ฐ ์บ์‹ฑ์œผ๋กœ ์กฐํšŒ ์„ฑ๋Šฅ ํ–ฅ์ƒ

๋ ˆ๋””์Šค๋ฅผ ์ด์šฉํ•ด ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ์—์„œ ํŽ˜์ด์ง• ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•˜์—ฌ ์กฐํšŒ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์— ์ˆ˜์ • ํ˜น์€ ์‚ญ์ œ ๋ฐœ์ƒ์ด ์บ์‹ฑ ๋‚ด์šฉ๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋˜๋„๋ก ํ•˜์˜€์œผ๋ฉฐ, 3์‹œ๊ฐ„์˜ ์œ ํšจ์‹œ๊ฐ„์„ ๊ฑธ์–ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

๋นˆ์ง‘ ๊ฑฐ๋ž˜ ์„œ๋น„์Šค ๋ก ์นญ์„ ์œ„ํ•œ ์‚ฌ์šฉ์ž ํƒ€์ž… ์ถ”๊ฐ€, ๊ณต์ธ์ค‘๊ฐœ์‚ฌ

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

๋นˆ์ง‘ ๊ฒŒ์‹œ๊ธ€ ๊ธ€์ž์ˆ˜ ์ œํ•œ, ์œ ํšจ์„ฑ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•œ Validator ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๊ธ€๊ณผ ๋‹ฌ๋ฆฌ ๋นˆ์ง‘ ๊ฒŒ์‹œ๊ธ€์€ 10,000์ž์˜ ๊ธ€์ž ์ˆ˜ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ์—๋Š” ์ˆœ์ˆ˜ํ•œ ๊ธ€์ž๋งŒ์ด ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ด๋ฏธ์ง€ ์ฃผ์†Œ, HTML ํƒœ๊ทธ ๋“ฑ ๋ถ€๊ฐ€์  ์š”์†Œ๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์š”์†Œ๋“ค์„ ํŒŒ์‹ฑํ•˜๋ฉด์„œ ์ œ์™ธ์‹œํ‚ค๊ณ  ์ˆœ์ˆ˜ํ•œ ๋‚ด์šฉ์— ๋Œ€ํ•œ ๊ธ€์ž ๊ธธ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด CodeValid ์–ด๋…ธํ…Œ์ด์…˜์„ ๋งŒ๋“ค๊ณ  ๋ณ„๋„์˜ validator๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

SSR ๋ฐฉ์‹์˜ ๋ฐฑ์˜คํ”ผ์Šค ๊ฐœ๋ฐœ

์ฃผ๋ง๋‚ด์ง‘์„ ์šด์˜ํ•˜๋Š” ๊ด€๋ฆฌ์ž๋งŒ์ด ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฑ์˜คํ”ผ์Šค๋ฅผ SSR ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

SSR ๋ฐฉ์‹์„ ์„ ํƒํ•œ ์ด์œ ๋Š” ์ œํ•œ๋œ ์ ‘๊ทผ์ž์™€ ์ ์€ ์ˆ˜์˜ ํŠธ๋ž˜ํ”ฝ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ ๋ฆฌ์†Œ์Šค๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•จ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฑ์˜คํ”ผ์Šค์—์„œ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž ์—ฐ๋ น๋Œ€๋ณ„ ๋น„์œจ, ์‚ฌ์šฉ์ž ๊ฐ€์ž…๊ฒฝ๋กœ ์‹œ๊ฐํ™”
  • ๊ฒŒ์‹œ๊ธ€ ์ƒ๋‹จ ๊ณ ์ • ๋ฐ ๊ณ ์ • ํ•ด์ œ
  • ๊ฒŒ์‹œ๊ธ€ ์˜๊ตฌ์‚ญ์ œ
  • ๊ณต์ธ์ค‘๊ฐœ์‚ฌ ํšŒ์› ๊ฐ€์ž… ์Šน์ธ/๋ฐ˜๋ ค
  • ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์˜ ๋นˆ์ง‘ ๋งค๋ฌผ ๋“ฑ๋ก ๊ฒŒ์‹œ๊ธ€ ์Šน์ธ/๋ฐ˜๋ ค
  • ์‹ ๊ณ  ์ฒ˜๋ฆฌ๋œ ๊ฒŒ์‹œ๊ธ€ ๊ด€๋ฆฌ

๊ด€๋ฆฌ์ž ๊ณ„์ •์œผ๋กœ์˜ ๋กœ๊ทธ์ธ์€ Session ๋ฐฉ์‹์„ ์ ์šฉํ•˜์˜€์œผ๋ฉฐ, interceptor๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€์— ๋กœ๊ทธ์ธ ์—†์ด ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

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

ํ™๋ณด ๊ฒŒ์‹œํŒ์€ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์œผ๋กœ ๊ด€๋ฆฌ์ž๊ฐ€ ๊ฒŒ์‹œ๊ธ€์„ ์ƒ๋‹จ์— ๊ณ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ์— ์ตœ๋Œ€ 10๊ฐœ์˜ ๊ฒŒ์‹œ๊ธ€์„ ๊ณ ์ •/๊ณ ์ •ํ•ด์ œ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋Š” ์œ„์— ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ํ™”๋ฉด์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํŽ˜์ด์ง€์—์„œ์˜ ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ๋Š” Soft delete ๋ฐฉ์‹์œผ๋กœ DB์—์„œ ์˜๊ตฌ์ ์œผ๋กœ ์‚ญ์ œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. DB์—์„œ ์˜๊ตฌ ์‚ญ์ œ๋Š” ๊ด€๋ฆฌ์ž๋งŒ์ด ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ์œ„ํ•ด ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ ๊ฒŒ์‹œ๊ธ€ ์˜๊ตฌ ์‚ญ์ œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ฃผ๋ง์ง‘ ์„œ๋น„์Šค์—๋Š” ๊ด€๋ฆฌ์ž, ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž, ๊ณต์ธ์ค‘๊ฐœ์‚ฌ ์œ ์ €๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ๊ด€๋ฆฌ์ž๋Š” ๊ณต์ธ์ค‘๊ฐœ์‚ฌ์˜ ํšŒ์›๊ฐ€์ž… ์Šน์ธ/๋ฐ˜๋ ค ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๊ณต์ธ์ค‘๊ฐœ์‚ฌ์™€ ๋‹ฌ๋ฆฌ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋Š” ๋นˆ์ง‘ ๋งค๋ฌผ์„ ๋“ฑ๋กํ•  ์‹œ, ๊ด€๋ฆฌ์ž์˜ ์Šน์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์ดํŠธ์—์„œ ์šด์˜ํ•˜๋Š” ๋นˆ์ง‘ ๊ฑฐ๋ž˜ ์ค‘๊ฐœ ์„œ๋น„์Šค์˜ ์‹ ๋ขฐ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ฃผ๋ง๋‚ด์ง‘ ๋งŒ์˜ ํ”„๋กœ์„ธ์Šค์ž…๋‹ˆ๋‹ค.

๊ณต์ธ์ค‘๊ฐœ์‚ฌ ํ˜น์€ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๊ฐ€ ์—…๋กœ๋“œํ•œ ๋นˆ์ง‘ ๊ฒŒ์‹œ๊ธ€์ด ํ—ˆ์œ„ ๊ฒŒ์‹œ๊ธ€์ด๊ฑฐ๋‚˜ ์ƒ์—…์  ๋ชฉ์ ์œผ๋กœ ์ž˜๋ชป๋œ ์ •๋ณด๋ฅผ ๊ธฐ์žฌํ•œ ๊ฒฝ์šฐ ์œ ์ €๋“ค๋กœ๋ถ€ํ„ฐ ์‹ ๊ณ ๋ฅผ ๋ฐ›์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ๊ฒŒ์‹œ๊ธ€์„ ์‚ญ์ œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

๋’ค์—์„œ ๋ฌต๋ฌตํžˆ ์—ญํ• ํ•˜๋Š” ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋Š” ์ง€์†์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ์ค‘์ž…๋‹ˆ๋‹ค.

๋กœ์ปฌ ๋กœ๊ทธ์ธ

๋กœ์ปฌ ๋กœ๊ทธ์ธ ๊ตฌํ˜„์„ ์œ„ํ•ด Spring Security๊ฐ€ ์•„๋‹Œ ArgumentResolver์™€ AOP๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

@Auth ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— HTTP Request Authorization Header์— ๋‹ด๊ธด JWT ํ† ํฐ์— ๋Œ€ํ•ด ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

@AuthUser ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ @Auth ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๊ฒ€์ฆ๋œ ํ† ํฐ ๊ฐ’์— ๋‹ด๊ธด ์‚ฌ์šฉ์ž์˜ ์•„์ด๋””๋กœ User๋ฅผ ์ฐพ์€ ํ›„, ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์˜ Argument๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋กœ์ปฌ ๋กœ๊ทธ์ธ ๊ตฌํ˜„ ๊ณผ์ •์€ Spring Security ์—†์ด ์ธ์ฆ์ธ๊ฐ€ ๊ตฌํ˜„ํ•˜๊ธฐ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ๊ถŒํ•œ ( ์ธ๊ฐ€ ํ”„๋กœ์„ธ์Šค ์ฒ˜๋ฆฌ )

๋กœ์ปฌ ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ํšŒ์›๊ฐ€์ž…์„ ํ•˜๋Š” ์‚ฌ์šฉ์ž๋Š” ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ๊ฐ€์ง€๋ฉฐ, ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์„ ๊ฐ–๋Š” ์‚ฌ์šฉ์ž๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Authority๋ฅผ ADMIN์œผ๋กœ ๋ถ€์—ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๋Š” ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ/์ˆ˜์ •/์‚ญ์ œ/์ƒ์„ฑ ๋ฐ ๋Œ“๊ธ€ ์ž‘์„ฑ/์ˆ˜์ •/์‚ญ์ œ, ์ข‹์•„์š” ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž๋Š” ์†Œ๊ฐœ ํŽ˜์ด์ง€ ๋‚ด ํ›„๊ธฐ/ํŠธ๋ Œ๋“œ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ/์ˆ˜์ •/์‚ญ์ œ ๊ถŒํ•œ์„ ๊ฐ€์ง€๋ฉฐ, ์ด๋Š” ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœ๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž๋Š” ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์˜ ์•…์˜์„ฑ ๊ฒŒ์‹œ๊ธ€ ๋ฐ ๋Œ“๊ธ€์— ๋Œ€ํ•ด ์˜๊ตฌ ์‚ญ์ œ ๊ถŒํ•œ์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

React-Quill ๊ธฐ๋ฐ˜ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ

๊ธ€ ์ž‘์„ฑ ์‹œ, ์•„๋ž˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž์œ ๋กญ๊ฒŒ ๊พธ๋ฐ€ ์ˆ˜ ์žˆ๋Š” ์—๋””ํ„ฐ ํ˜•์‹์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

img_2.png

๋Œ€ํ‘œ ์ธ๋„ค์ผ ์ด๋ฏธ์ง€์™€ ๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ์— ํฌํ•จ๋˜๋Š” ์ด๋ฏธ์ง€์— ๋Œ€ํ•ด์„œ๋Š” Frontend ์ธก์—์„œ AWS S3๋กœ ์ง์ ‘ ์—…๋กœ๋“œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํ›„ url ์ฃผ์†Œ์— ๋Œ€ํ•ด์„œ Server๋กœ ๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ ์ „๋‹ฌํ•˜์—ฌ DB์—์„œ ์ด๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… (2023.04.17)
๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ์ตœ๋Œ€ ํฌ๊ธฐ ์ดˆ๊ณผ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Board(Id, CreatedAt, UpdatedAt, Category, Code, Content, Fixed, FixedAt, ImageUrls, PrefixCategory, Title, UseYn, UserId )

๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ”์€ ์œ„์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ ๋˜์–ด ์žˆ์—ˆ์œผ๋ฉฐ, Code ์ปฌ๋Ÿผ์€ Frontend ์ธก์—์„œ ๋„˜์–ด์˜ค๋Š” HTML ํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰ ์‹œ, ๊ฒŒ์‹œ๊ธ€์˜ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์— ๋Œ€ํ•ด ๊ฒ€์ƒ‰์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ–ˆ๊ธฐ์— ๊ฒŒ์‹œ๊ธ€ ๋ฐ์ดํ„ฐ๊ฐ€ insert ๋˜๊ธฐ ์ด์ „์— Code ๋ฐ์ดํ„ฐ๋กœ๋ถ€ํ„ฐ HTML ํƒœ๊ทธ๋ฅผ ํŒŒ์‹ฑํ•ด์„œ ์ˆœ์ˆ˜ํ•œ ๊ฐ’๋งŒ ๊ฐ–๋Š” Content ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ„๋„์˜ ์ปฌ๋Ÿผ์œผ๋กœ ์ €์žฅํ•˜์—ฌ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ” ๋‚ด์— ์ด๋ฏธ ๋งŽ์€ ์ปฌ๋Ÿผ์ด ์กด์žฌํ•˜๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ๊ฒŒ์‹œ๊ธ€์˜ ๊ธ€์ž์ˆ˜ ์ œํ•œ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— Code์™€ Content ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ํ•˜๋‚˜์˜ Row๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ๋„˜์–ด์„œ๋ฉด์„œ insert ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ด๋ธ”์„ ๋ถ„๋ฆฌํ•˜์—ฌ board์™€ board_code๋ฅผ One-To-One์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Code ์ปฌ๋Ÿผ์€ TEXT ํƒ€์ž…์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ ๋ฐ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ์ด์Šˆ์˜ ๋ฐœ์ƒ ๊ณผ์ • ๋ฐ ํ•ด๊ฒฐ ๊ณผ์ •์€ ๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ ํฌ๊ธฐ ์ดˆ๊ณผ๋กœ ์ธํ•œ ํ…Œ์ด๋ธ” ๋ถ„๋ฆฌ ์ž‘์—…์—์„œ ์ž์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Soft Delete ๋ฐฉ์‹์˜ ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์–ป๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์šด์˜๋˜๋Š” ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ๊ณง ์ž์‚ฐ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋ˆ„์ ๋˜์–ด ๊ทธ ์•ˆ์—์„œ ์œ ์˜๋ฏธํ•œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ณ , ์ด๊ฒƒ์ด ์‹ ๊ทœ ๊ธฐ๋Šฅ์ด์ž ์„œ๋น„์Šค๋กœ ๋ฐœ์ „๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐํš์˜ ์š”๊ตฌ์‚ฌํ•ญ ๋ณ€๊ฒฝ์œผ๋กœ ์‚ญ์ œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๋…ธ์ถœํ•ด์•ผ ํ•˜๋Š” ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ์ƒํ™ฉ์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด Soft Delete ๋ฐฉ์‹์„ ์ ์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ” ๋‚ด์— UseYn ์ปฌ๋Ÿผ์„ ๋‘์–ด ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒŒ์‹œ๊ธ€์„ ์‚ญ์ œํ•œ ๊ฒฝ์šฐ์—๋Š” ์กฐํšŒ๋˜์ง€ ์•Š๊ณ , ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์—์„œ ๊ด€๋ฆฌ์ž๊ฐ€ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜๊ตฌ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

soft delete ์ ์šฉ ๊ณผ์ •์€ Soft Delete ๋ฐฉ์‹ ์ ์šฉ์—์„œ ์ž์„ธํžˆ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ์™ธ ํšŒ๊ณ  ๋ฐ ๋ฌธ์„œํ™”

ํŒ€ ๊ตฌ์„ฑ

Name ์ด์€๋น„ ์œคํƒœ๋ฏผ ๋ฌธ๋ฏผํ˜
Profile
Role Team Leader
Back-end, DevOps
Back-end,
DevOps
Back-end ,
DevOps
Part ํ”„๋กœ์ ํŠธ ์„ธํŒ…
์ปค๋ฎค๋‹ˆํ‹ฐ API
๋นˆ์ง‘ ๊ฑฐ๋ž˜ API
ํ…Œํฌ ๋ธ”๋กœ๊ทธ ํ”„๋ก ํŠธ์—”๋“œ 100% ๊ฐœ๋ฐœ
์ „์ฒด ์„œ๋น„์Šค ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ๊ด€๋ฆฌ์žํŽ˜์ด์ง€ ์ผ๋ถ€ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ
์ธํ”„๋ผ ์„ธํŒ…
๊ด€๋ฆฌ์žํŽ˜์ด์ง€(SSR) 100% ๊ฐœ๋ฐœ
์„ฑ๋Šฅ ๊ฐœ์„ (์บ์‹ฑ, ๋™์ ์ฟผ๋ฆฌ ๋ฆฌํŽ™ํ† ๋ง)
์‚ฌ์šฉ์ž API
๋งˆ์ดํŽ˜์ด์ง€ API
DDoS ๋ฐฉ์ง€ ์ฒ˜๋ฆฌ
ํ…Œํฌ ๋ธ”๋กœ๊ทธ API 100% ๊ฐœ๋ฐœ
GitHub @dldmsql @YoonTaeMinnnn @MoonMinHyuk1

About

๐Ÿ  ์ฃผ๋ง๋‚ด์ง‘, ๋“€์–ผ ๋ผ์ดํ”„ ์ปค๋ฎค๋‹ˆํ‹ฐ ๐Ÿ 

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages