2025๋…„ 3์›” 02์ผยท6๋ถ„ ์ฝ๊ธฐ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX: ์‹คํŒจ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊พธ๊ธฐ

์•ฑ์—์„œ ๊ณ ์œ  ์ œ์•ฝ, ์™ธ๋ž˜ ํ‚ค, NOT NULL ์‹คํŒจ๋ฅผ ํ•„๋“œ ์ˆ˜์ค€์˜ ๋„์›€์ด ๋˜๋Š” ๋ฉ”์‹œ์ง€๋กœ ๋งคํ•‘ํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์„ธ์š”.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX: ์‹คํŒจ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊พธ๊ธฐ

์ œ์•ฝ ์‹คํŒจ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์™œ ๋ถˆ์พŒํ•˜๊ฒŒ ๋А๊ปด์ง€๋Š”๊ฐ€

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

๋ฐ”๋กœ ๊ทธ ๊ฐ„๊ทน ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX๊ฐ€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด์ง€ ๋ชปํ•œ ๊ทœ์น™์„ ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค: โ€œ์ด ๊ฐ’์€ ๊ณ ์œ ํ•ด์•ผ ํ•œ๋‹คโ€, โ€œ์ด ๋ ˆ์ฝ”๋“œ๋Š” ์กด์žฌํ•˜๋Š” ํ•ญ๋ชฉ์„ ์ฐธ์กฐํ•ด์•ผ ํ•œ๋‹คโ€, โ€œ์ด ํ•„๋“œ๋Š” ๋น„์›Œ๋‘˜ ์ˆ˜ ์—†๋‹ค.โ€ ์•ฑ์ด ์ด๋Ÿฐ ๊ทœ์น™์„ ๋ชจํ˜ธํ•œ ์˜ค๋ฅ˜ ๋’ค์— ์ˆจ๊ธฐ๋ฉด ์‚ฌ์šฉ์ž๋Š” ์ดํ•ดํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๋กœ ํƒ“์„ ๋ฐ›๋Š” ๊ธฐ๋ถ„์ด ๋“ญ๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ์˜ค๋ฅ˜๋Š” ์‹ ๋ขฐ๋„๋„ ๊นŽ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์•ฑ์ด ๋ถˆ์•ˆ์ •ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด ์žฌ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ๊ณ ์นจํ•˜๊ฑฐ๋‚˜ ์ž‘์—…์„ ํฌ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฌด ํ™˜๊ฒฝ์—์„œ๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š๋Š” ์Šคํฌ๋ฆฐ์ƒท๊ณผ ํ•จ๊ป˜ ์ง€์›์— ๋ฌธ์˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค(์Šคํฌ๋ฆฐ์ƒท์—๋Š” ์“ธ๋ชจ์žˆ๋Š” ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค).

ํ”ํ•œ ์˜ˆ: ๊ณ ๊ฐ์„ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ โ€œ์ €์žฅ ์‹คํŒจโ€๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ฐ™์€ ์ด๋ฉ”์ผ๋กœ ๋‹ค์‹œ ์‹œ๋„ํ•ด๋„ ์‹คํŒจํ•˜๋ฉด ์‚ฌ์šฉ์ž๋Š” ์‹œ์Šคํ…œ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘๋ณต ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์žƒ์–ด๋ฒ„๋ฆฌ๋Š”์ง€ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” UI์—์„œ ๊ฒ€์ฆํ•˜๋”๋ผ๋„ ๋งˆ์ง€๋ง‰์˜ ์ง„์‹ค ์†Œ์Šค์ธ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ๋ณ€๊ฒฝ, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…, ํ†ตํ•ฉ์œผ๋กœ ์ตœ์‹  ์ƒํƒœ๋ฅผ ๋ณด๋ฏ€๋กœ ์ œ์•ฝ ์‹คํŒจ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ๊ฒฐ๊ณผ๋Š” ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ทœ์น™์„ ํŠน์ • ํ•„๋“œ์™€ ๋‹ค์Œ ๋‹จ๊ณ„(์–ด๋–ค ์กฐ์น˜๋ฅผ ์ทจํ• ์ง€)๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • โ€œ์ด ์ด๋ฉ”์ผ์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ด๋ฉ”์ผ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ์ธํ•˜์„ธ์š”.โ€
  • โ€œ์œ ํšจํ•œ ๊ณ„์ •์„ ์„ ํƒํ•˜์„ธ์š”. ์„ ํƒํ•œ ๊ณ„์ •์ด ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.โ€
  • โ€œ์ „ํ™”๋ฒˆํ˜ธ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.โ€

์ด ๊ธ€์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์€ ์‹คํŒจ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋„์›€์ด ๋˜๋Š” ์•ˆ๋‚ด๋กœ '๋ฒˆ์—ญ'ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง์ ‘ ์Šคํƒ์„ ๊ตฌํ˜„ํ•˜๋“  AppMaster ๊ฐ™์€ ๋„๊ตฌ๋กœ ๋งŒ๋“ค๋“  ๋ชฉํ‘œ๋Š” ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋งˆ์ฃผ์น˜๊ฒŒ ๋  ์ œ์•ฝ ์œ ํ˜•(๊ทธ๋ฆฌ๊ณ  ๊ทธ ์˜๋ฏธ)

๋Œ€๋ถ€๋ถ„์˜ โ€œ์š”์ฒญ ์‹คํŒจโ€ ์ˆœ๊ฐ„์€ ์†Œ์ˆ˜์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ทœ์น™์—์„œ ์˜ต๋‹ˆ๋‹ค. ๊ทœ์น™์˜ ์ด๋ฆ„์„ ์•Œ๋ฉด ๋ณดํ†ต ์˜ค๋ฅธ์ชฝ ํ•„๋“œ์— ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ์ œ์•ฝ ์œ ํ˜•์„ ํ‰์ดํ•œ ์–ธ์–ด๋กœ ์ •๋ฆฌํ•˜๋ฉด:

  • ๊ณ ์œ  ์ œ์•ฝ(Unique constraint): ๊ฐ’์ด ๊ณ ์œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฉ”์ผ, ์‚ฌ์šฉ์ž๋ช…, ์†ก์žฅ ๋ฒˆํ˜ธ, ์™ธ๋ถ€ ID ๋“ฑ์ด ํ”ํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์‹คํŒจํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ โ€œ์ž˜๋ชปํ–ˆ๋‹คโ€๊ธฐ๋ณด๋‹ค ๊ธฐ์กด ๋ฐ์ดํ„ฐ์™€ ์ถฉ๋Œํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์™ธ๋ž˜ ํ‚ค ์ œ์•ฝ(Foreign key constraint): ํ•œ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•˜๋Š” ๋‹ค๋ฅธ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค(์˜ˆ: order.customer_id). ์ฐธ์กฐ ๋Œ€์ƒ์ด ์‚ญ์ œ๋๊ฑฐ๋‚˜ ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ UI๊ฐ€ ์ž˜๋ชป๋œ ID๋ฅผ ๋ณด๋ƒˆ์„ ๋•Œ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
  • NOT NULL ์ œ์•ฝ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ˆ˜์ค€์—์„œ ํ•„์ˆ˜ ๊ฐ’์ด ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ํผ์ด ์™„์ „ํ•ด ๋ณด์—ฌ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: UI๊ฐ€ ํ•„๋“œ๋ฅผ ๋ณด๋‚ด์ง€ ์•Š์•˜๊ฑฐ๋‚˜ API๊ฐ€ ๋ฎ์–ด์ผ์„ ๋•Œ).
  • ์ฒดํฌ ์ œ์•ฝ(Check constraint): ๊ฐ’์ด ํ—ˆ์šฉ ๊ทœ์น™์„ ๋ฒ—์–ด๋‚  ๋•Œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด โ€œ์ˆ˜๋Ÿ‰์€ 0๋ณด๋‹ค ์ปค์•ผ ํ•จโ€, โ€œ์ƒํƒœ๋Š” ๋ฏธ๋ฆฌ ์ •ํ•œ ๊ฐ’ ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•จโ€, โ€œํ• ์ธ์€ 0~100 ์‚ฌ์ด์—ฌ์•ผ ํ•จโ€ ๊ฐ™์€ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.

๊ฐ™์€ ์‹ค์ œ ๋ฌธ์ œ๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ๋„๊ตฌ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Postgres๋Š” ์ œ์•ฝ ์ด๋ฆ„์„ ์ฃผ๊ธฐ๋„ ํ•ด ๋„์›€์ด ๋˜์ง€๋งŒ ORM์€ ์ด๋ฅผ ์ผ๋ฐ˜ ์˜ˆ์™ธ๋กœ ๋ž˜ํ•‘ํ•ด ์œ ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ ๊ณ ์œ  ์ œ์•ฝ๋„ โ€œduplicate keyโ€, โ€œunique violationโ€ ๋˜๋Š” ๊ณต๊ธ‰์‚ฌ๋ณ„ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์šฉ์  ์˜ˆ: ๊ด€๋ฆฌ ํŒจ๋„์—์„œ ๊ณ ๊ฐ์„ ์ˆ˜์ •ํ•˜๊ณ  ์ €์žฅํ–ˆ๋Š”๋ฐ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. API๊ฐ€ email์— ๋Œ€ํ•œ ๊ณ ์œ  ์ œ์•ฝ์ž„์„ UI์— ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๋ชจํ˜ธํ•œ ํ† ์ŠคํŠธ ๋Œ€์‹  ์ด๋ฉ”์ผ ํ•„๋“œ ์•„๋ž˜์— โ€œ์ด ์ด๋ฉ”์ผ์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹คโ€๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์ œ์•ฝ ์œ ํ˜•์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ทจํ•  ๋‹ค์Œ ํ–‰๋™์— ๋Œ€ํ•œ ํžŒํŠธ๋กœ ๋‹ค๋ฃจ์„ธ์š”: ๋‹ค๋ฅธ ๊ฐ’์„ ์„ ํƒํ•˜๊ธฐ, ์กด์žฌํ•˜๋Š” ๊ด€๋ จ ๋ ˆ์ฝ”๋“œ ์„ ํƒํ•˜๊ธฐ, ๋ˆ„๋ฝ๋œ ํ•„๋“œ ์ฑ„์šฐ๊ธฐ ๋“ฑ์ž…๋‹ˆ๋‹ค.

์ข‹์€ ํ•„๋“œ ์ˆ˜์ค€ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•ด์•ผ ํ•  ์ผ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์‹คํŒจ๋Š” ๊ธฐ์ˆ ์  ์ด๋ฒคํŠธ์ด์ง€๋งŒ ๊ฒฝํ—˜์€ ์ผ๋ฐ˜ ์•ˆ๋‚ด์ฒ˜๋Ÿผ ๋А๊ปด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ข‹์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX๋Š” โ€œ๋ญ”๊ฐ€ ๊ณ ์žฅ๋‚จโ€์„ โ€œ์—ฌ๊ธฐ์„œ ๋ฌด์—‡์„ ๊ณ ์ณ์•ผ ํ•˜๋Š”์ง€โ€๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

ํ‰์ดํ•œ ์–ธ์–ด๋ฅผ ์“ฐ์„ธ์š”. โ€œunique indexโ€๋‚˜ โ€œforeign keyโ€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์šฉ์–ด๋ฅผ ์‚ฌ๋žŒ ๋ง๋กœ ๋ฐ”๊พธ์„ธ์š”. โ€œ์ด ์ด๋ฉ”์ผ์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹คโ€๋Š” โ€œduplicate key value violates unique constraintโ€๋ณด๋‹ค ํ›จ์”ฌ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋™์ž‘์ด ์ผ์–ด๋‚˜๋Š” ๊ณณ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋‘์„ธ์š”. ์˜ค๋ฅ˜๊ฐ€ ๋ช…ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ž…๋ ฅ์— ์†ํ•˜๋ฉด ํ•ด๋‹น ํ•„๋“œ์— ๋ถ™์—ฌ ์ฆ‰์‹œ ๊ณ ์น  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์„ธ์š”. ์ „์ฒด ๋™์ž‘ ๋•Œ๋ฌธ์— ์‹คํŒจํ•œ ๊ฒฝ์šฐ(์˜ˆ: โ€œ์ด ํ•ญ๋ชฉ์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉ ์ค‘์ด๋ผ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Œโ€)์—๋Š” ์ €์žฅ ๋ฒ„ํŠผ ๊ทผ์ฒ˜ ๊ฐ™์€ ํผ ์ˆ˜์ค€์— ๋ช…ํ™•ํ•œ ๋‹ค์Œ ๋‹จ๊ณ„์™€ ํ•จ๊ป˜ ๋ณด์—ฌ์ฃผ์„ธ์š”.

๊ตฌ์ฒด์„ฑ์ด ์ •์ค‘ํ•จ๋ณด๋‹ค ๋‚ซ์Šต๋‹ˆ๋‹ค. ์œ ์šฉํ•œ ๋ฉ”์‹œ์ง€๋Š” ๋‘ ๊ฐ€์ง€ ์งˆ๋ฌธ์— ๋‹ตํ•ฉ๋‹ˆ๋‹ค: ๋ฌด์—‡์„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š”๊ฐ€, ๊ทธ๋ฆฌ๊ณ  ๊ฑฐ์ ˆ๋œ ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€. โ€œ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์„ ํƒํ•˜์„ธ์š”โ€๋Š” โ€œ์ž˜๋ชป๋œ ์‚ฌ์šฉ์ž ์ด๋ฆ„โ€๋ณด๋‹ค ๋‚ซ์Šต๋‹ˆ๋‹ค. โ€œ์ €์žฅํ•˜๊ธฐ ์ „์— ๊ณ ๊ฐ์„ ์„ ํƒํ•˜์„ธ์š”โ€๋Š” โ€œ๋ฐ์ดํ„ฐ ๋ˆ„๋ฝโ€๋ณด๋‹ค ๋‚ซ์Šต๋‹ˆ๋‹ค.

๋ฏผ๊ฐํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๋•Œ๋กœ ๊ฐ€์žฅ โ€˜๋„์›€์ด ๋˜๋Š”โ€™ ๋ฉ”์‹œ์ง€๊ฐ€ ์ •๋ณด๋ฅผ ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์ด๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ํ™”๋ฉด์—์„œ โ€œ์ด ์ด๋ฉ”์ผ๋กœ๋Š” ๊ณ„์ •์ด ์—†์Šต๋‹ˆ๋‹คโ€๋ผ๊ณ  ํ•˜๋ฉด ๊ณต๊ฒฉ์ž์—๊ฒŒ ์œ ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” โ€œ์ผ์น˜ํ•˜๋Š” ๊ณ„์ •์ด ์žˆ์œผ๋ฉด ์ด๋ฉ”์ผ์„ ๋ฐœ์†กํ•ฉ๋‹ˆ๋‹คโ€์ฒ˜๋Ÿผ ์•ˆ์ „ํ•œ ๋ฌธ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

๋˜ํ•œ ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ์„ ๊ณ„ํšํ•˜์„ธ์š”. ํ•˜๋‚˜์˜ ์ €์žฅ์ด ์—ฌ๋Ÿฌ ์ œ์•ฝ์—์„œ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UI๋Š” ์—ฌ๋Ÿฌ ํ•„๋“œ ๋ฉ”์‹œ์ง€๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ํ™”๋ฉด์„ ์–ด์ˆ˜์„ ํ•˜๊ฒŒ ๋งŒ๋“ค์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ•๋ ฅํ•œ ํ•„๋“œ ์ˆ˜์ค€ ๋ฉ”์‹œ์ง€๋Š” ํ‰์ดํ•œ ๋‹จ์–ด๋ฅผ ์“ฐ๊ณ , ์˜ฌ๋ฐ”๋ฅธ ํ•„๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ(๋˜๋Š” ๋ช…ํ™•ํ•œ ํผ ์ˆ˜์ค€์ž„์„ ํ‘œ์‹œ), ์‚ฌ์šฉ์ž๊ฐ€ ๋ฌด์—‡์„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ , ๊ณ„์ •์ด๋‚˜ ๋ ˆ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฏผ๊ฐํ•œ ์‚ฌ์‹ค์„ ๋…ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํ•˜๋‚˜์˜ ์‘๋‹ต์—์„œ ์—ฌ๋Ÿฌ ์˜ค๋ฅ˜๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

API์™€ UI ์‚ฌ์ด์˜ ์—๋Ÿฌ ๊ณ„์•ฝ ์„ค๊ณ„

์ข‹์€ UX๋Š” ํ•ฉ์˜์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค: ์‹คํŒจํ•  ๋•Œ API๋Š” UI์— ์ •ํ™•ํžˆ ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ , UI๋Š” ํ•ญ์ƒ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ทธ ๊ณ„์•ฝ์ด ์—†์œผ๋ฉด ๊ฒฐ๊ตญ ์•„๋ฌด๋„ ๋„์›€์ด ๋˜์ง€ ์•Š๋Š” ๋ชจํ˜ธํ•œ ํ† ์ŠคํŠธ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค.

์‹ค์šฉ์ ์ธ ์—๋Ÿฌ ํ˜•ํƒœ๋Š” ์ž‘์ง€๋งŒ ๊ตฌ์ฒด์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ์—๋Ÿฌ ์ฝ”๋“œ, ํ•„๋“œ(๋‹จ์ผ ์ž…๋ ฅ์œผ๋กœ ๋งคํ•‘๋  ๋•Œ), ์‚ฌ๋žŒ์šฉ ๋ฉ”์‹œ์ง€, ๋กœ๊น…์šฉ ์„ ํƒ์  ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋‹ด์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

{
  "error": {
    "code": "UNIQUE_VIOLATION",
    "field": "email",
    "message": "That email is already in use.",
    "details": {
      "constraint": "users_email_key",
      "table": "users"
    }
  }
}

ํ•ต์‹ฌ์€ ์•ˆ์ •์„ฑ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ์›์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…์ŠคํŠธ๋ฅผ ๋…ธ์ถœํ•˜์ง€ ๋ง๊ณ , UI๊ฐ€ Postgres ์—๋Ÿฌ ๋ฌธ์ž์—ด์„ ํŒŒ์‹ฑํ•˜๊ฒŒ ํ•˜์ง€ ๋งˆ์„ธ์š”. ์ฝ”๋“œ๋Š” ์›น, iOS, Android ๊ฐ™์€ ํ”Œ๋žซํผ๊ณผ ์—”๋“œํฌ์ธํŠธ ์ „๋ฐ˜์—์„œ ์ผ๊ด€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•„๋“œ ์˜ค๋ฅ˜์™€ ํผ ์ˆ˜์ค€ ์˜ค๋ฅ˜๋ฅผ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ• ์ง€ ๋ฏธ๋ฆฌ ์ •ํ•˜์„ธ์š”. ํ•„๋“œ ์˜ค๋ฅ˜๋Š” ํ•œ ์ž…๋ ฅ์ด ๋ง‰ํ˜”์Œ์„ ๋œปํ•ฉ๋‹ˆ๋‹ค(field๋ฅผ ์„ค์ •ํ•˜๊ณ  ์ž…๋ ฅ ์•„๋ž˜ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ). ํผ ์ˆ˜์ค€ ์˜ค๋ฅ˜๋Š” ํ•„๋“œ๋“ค์€ ์œ ํšจํ•ด ๋ณด์—ฌ๋„ ๋™์ž‘์„ ์™„๋ฃŒํ•  ์ˆ˜ ์—†์„ ๋•Œ ์‚ฌ์šฉํ•˜์„ธ์š”(field๋ฅผ ๋น„์›Œ ์ €์žฅ ๋ฒ„ํŠผ ๊ทผ์ฒ˜์— ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ). ์—ฌ๋Ÿฌ ํ•„๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํŒจํ•  ์ˆ˜ ์žˆ์œผ๋ฉด field์™€ code๋ฅผ ๊ฐ€์ง„ ์˜ค๋ฅ˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜์„ธ์š”.

๋ Œ๋”๋ง์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜๋ ค๋ฉด UI ๊ทœ์น™์„ ์ง€๋ฃจํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ์„ธ์š”: ์ฒซ ๋ฒˆ์งธ ์˜ค๋ฅ˜๋ฅผ ์งง์€ ์š”์•ฝ์œผ๋กœ ์ƒ๋‹จ์— ๋ณด์—ฌ์ฃผ๊ณ  ํ•„๋“œ ์˜†์— ์ธ๋ผ์ธ์œผ๋กœ ํ‘œ์‹œ, ๋ฉ”์‹œ์ง€๋Š” ์งง๊ณ  ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์œ ์ง€, ๋ชจ๋“  ํ๋ฆ„(signup, profile edit, admin ๋“ฑ)์—์„œ ๋™์ผํ•œ ๋ฌธ๊ตฌ ์žฌ์‚ฌ์šฉ, details๋Š” ๋กœ๊น…์šฉ์œผ๋กœ ๋‚จ๊ธฐ๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” message๋งŒ ๋ณด์—ฌ์ฃผ๊ธฐ.

AppMaster๋กœ ๋นŒ๋“œํ•œ๋‹ค๋ฉด ์ด ๊ณ„์•ฝ์„ ๋‹ค๋ฅธ API ์ถœ๋ ฅ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ทจ๊ธ‰ํ•˜์„ธ์š”. ๋ฐฑ์—”๋“œ๊ฐ€ ๊ตฌ์กฐํ™”๋œ ํ˜•ํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์ƒ์„ฑ๋œ ์›น(Vue3)๊ณผ ๋ชจ๋ฐ”์ผ ์•ฑ์ด ํ•˜๋‚˜์˜ ๊ณตํ†ต ํŒจํ„ด์œผ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด ๋ชจ๋“  ์ œ์•ฝ ์‹คํŒจ๊ฐ€ ์•ˆ๋‚ด์ฒ˜๋Ÿผ ๋А๊ปด์ง€๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ๊ณ„๋ณ„: DB ์˜ค๋ฅ˜๋ฅผ ํ•„๋“œ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊พธ๊ธฐ

Ship the same UX to production
Deploy to AppMaster Cloud or your preferred cloud when your validation flow is ready.
Start building

์ข‹์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ตœ์ข… ํŒ์‚ฌ๋กœ ๋ณด๊ณ  ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์›์‹œ SQL ํ…์ŠคํŠธ๋‚˜ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ๋ณด์•„์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ํ•„๋“œ๋ฅผ ๊ณ ์ณ์•ผ ํ•˜๋Š”์ง€์™€ ๋‹ค์Œ ๋‹จ๊ณ„๊ฐ€ ๋ณด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„ ์Šคํƒ์—์„œ ๋™์ž‘ํ•˜๋Š” ์‹ค์šฉ์  ํ๋ฆ„:

  1. ์˜ค๋ฅ˜๋ฅผ ์–ด๋””์„œ ์žก์„์ง€ ๊ฒฐ์ •ํ•˜์„ธ์š”. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์˜ค๋ฅ˜๊ฐ€ API ์‘๋‹ต์œผ๋กœ ๋ฐ”๋€Œ๋Š” ํ•œ ๊ณณ์„ ์ •ํ•˜์„ธ์š”(๋ณดํ†ต ๋ฆฌํฌ์ง€ํ† ๋ฆฌ/DAO ๋ ˆ์ด์–ด๋‚˜ ์ „์—ญ ์˜ค๋ฅ˜ ํ•ธ๋“ค๋Ÿฌ). ๊ทธ๋ž˜์•ผ โ€œ๊ฐ€๋”์€ ์ธ๋ผ์ธ, ๊ฐ€๋”์€ ํ† ์ŠคํŠธโ€ ๊ฐ™์€ ํ˜ผ๋ž€์ด ์ƒ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ์‹คํŒจ๋ฅผ ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ์“ฐ๊ธฐ ์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด ๊ณ ์œ  ์ œ์•ฝ, ์™ธ๋ž˜ ํ‚ค, NOT NULL, ์ฒดํฌ ์ œ์•ฝ ๋“ฑ์œผ๋กœ ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ๊ฐ€๋Šฅํ•˜๋ฉด ๋“œ๋ผ์ด๋ฒ„ ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋ถ€๋“์ดํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด ์‚ฌ๋žŒ ํ…์ŠคํŠธ๋ฅผ ํŒŒ์‹ฑํ•˜์ง€ ๋งˆ์„ธ์š”.
  3. ์ œ์•ฝ๋ช…์„ ํผ ํ•„๋“œ์— ๋งคํ•‘ํ•˜์„ธ์š”. ์ œ์•ฝ๋ช…์€ ์ข‹์€ ์‹๋ณ„์ž์ง€๋งŒ UI๋Š” ํ•„๋“œ ํ‚ค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์กฐํšŒํ‘œ๋ฅผ ๋‘์„ธ์š”: users_email_key -> email, orders_customer_id_fkey -> customerId. ์ด ๋งคํ•‘์€ ์Šคํ‚ค๋งˆ๋ฅผ ์†Œ์œ ํ•œ ์ฝ”๋“œ ๊ทผ์ฒ˜์— ๋‘์„ธ์š”.
  4. ์•ˆ์ „ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”. DB ์›๋ฌธ ๋Œ€์‹  ์ œ์•ฝ ์œ ํ˜•๋ณ„๋กœ ์งง๊ณ  ์‚ฌ์šฉ์ž ์นœํ™”์ ์ธ ๋ฌธ๊ตฌ๋ฅผ ๋งŒ๋“œ์„ธ์š”. Unique -> โ€œ์ด ๊ฐ’์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹ค.โ€ FK -> โ€œ๊ธฐ์กด ๊ณ ๊ฐ์„ ์„ ํƒํ•˜์„ธ์š”.โ€ NOT NULL -> โ€œ์ด ํ•„๋“œ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.โ€ Check -> โ€œ๊ฐ’์ด ํ—ˆ์šฉ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค.โ€
  5. ๊ตฌ์กฐํ™”๋œ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ธ๋ผ์ธ์œผ๋กœ ๋ Œ๋”ํ•˜์„ธ์š”. ์ผ๊ด€๋œ ํŽ˜์ด๋กœ๋“œ(์˜ˆ: [{ field, code, message }])๋ฅผ ๋ณด๋‚ด์„ธ์š”. UI์—์„œ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ•„๋“œ์— ๋ถ™์ด๊ณ  ์ฒซ ์‹คํŒจ ํ•„๋“œ๋กœ ์Šคํฌ๋กคํ•˜๊ณ  ํฌ์ปค์Šคํ•˜๋ฉฐ, ๊ธ€๋กœ๋ฒŒ ๋ฐฐ๋„ˆ๋Š” ์š”์•ฝ ์šฉ๋„๋กœ๋งŒ ์“ฐ์„ธ์š”.

AppMaster๋กœ ๋นŒ๋“œํ•œ๋‹ค๋ฉด ๊ฐ™์€ ์ƒ๊ฐ์„ ์ ์šฉํ•˜์„ธ์š”: ๋ฐฑ์—”๋“œ์—์„œ DB ์˜ค๋ฅ˜๋ฅผ ํ•œ ๊ณณ์—์„œ ์žก์•„ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ํ•„๋“œ ์˜ค๋ฅ˜ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์›น ํ˜น์€ ๋ชจ๋ฐ”์ผ UI์—์„œ ์ž…๋ ฅ ์˜†์— ๋ณด์—ฌ์ฃผ๋ฉด ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์ด ๋ฐ”๋€Œ์–ด๋„ ๊ฒฝํ—˜์ด ์ผ๊ด€๋ฉ๋‹ˆ๋‹ค.

ํ˜„์‹ค์ ์ธ ์˜ˆ: ์„ธ ๋ฒˆ์˜ ์ €์žฅ ์‹คํŒจ, ์„ธ ๊ฐ€์ง€ ์œ ์šฉํ•œ ๊ฒฐ๊ณผ

์ด ์‹คํŒจ๋“ค์€ ์ข…์ข… ํ•˜๋‚˜์˜ ์ผ๋ฐ˜ ํ† ์ŠคํŠธ๋กœ ๋ญ‰๊ฐœ์ง‘๋‹ˆ๋‹ค. ๊ฐ ์ƒํ™ฉ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์™”๋”๋ผ๋„ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

1) ๊ฐ€์ž…: ์ด๋ฉ”์ผ์ด ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘(๊ณ ์œ  ์ œ์•ฝ)

์›์‹œ ์‹คํŒจ(๋กœ๊ทธ์— ๋ณด์ด๋Š” ๊ฒƒ): duplicate key value violates unique constraint "users_email_key"

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๊ฒƒ: โ€œํ•ด๋‹น ์ด๋ฉ”์ผ์€ ์ด๋ฏธ ๋“ฑ๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ด๋ฉ”์ผ์„ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”.โ€

์ด๋ฉ”์ผ ํ•„๋“œ ์˜†์— ๋ฉ”์‹œ์ง€๋ฅผ ๋‘๊ณ  ํผ ์ž…๋ ฅ์€ ์œ ์ง€ํ•˜์„ธ์š”. ๊ฐ€๋Šฅํ•˜๋ฉด โ€œ๋กœ๊ทธ์ธโ€ ๊ฐ™์€ 2์ฐจ ํ–‰๋™์„ ์ œ๊ณตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์Œ์— ๋ฌด์—‡์„ ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ฒŒ ํ•˜์„ธ์š”.

2) ์ฃผ๋ฌธ ์ƒ์„ฑ: ๊ณ ๊ฐ ๋ˆ„๋ฝ(์™ธ๋ž˜ ํ‚ค)

์›์‹œ ์‹คํŒจ: insert or update on table "orders" violates foreign key constraint "orders_customer_id_fkey"

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๊ฒƒ: โ€œ์ฃผ๋ฌธ์„ ์œ„ํ•ด ๊ณ ๊ฐ์„ ์„ ํƒํ•˜์„ธ์š”.โ€

์ด๊ฑด ์‚ฌ์šฉ์ž์—๊ฒŒ โ€˜์˜ค๋ฅ˜โ€™๋ผ๊ธฐ๋ณด๋‹ค ๋งฅ๋ฝ ๋ˆ„๋ฝ์œผ๋กœ ๋А๊ปด์ง‘๋‹ˆ๋‹ค. ๊ณ ๊ฐ ์„ ํƒ๊ธฐ(Customer selector)๋ฅผ ๊ฐ•์กฐํ•˜๊ณ  ์ด๋ฏธ ์ถ”๊ฐ€ํ•œ ๋ผ์ธ ํ•ญ๋ชฉ์€ ์œ ์ง€ํ•˜์„ธ์š”. ๋งŒ์•ฝ ๋‹ค๋ฅธ ํƒญ์—์„œ ๊ณ ๊ฐ์ด ์‚ญ์ œ๋˜์—ˆ๋‹ค๋ฉด โ€œํ•ด๋‹น ๊ณ ๊ฐ์€ ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ณ ๊ฐ์„ ์„ ํƒํ•˜์„ธ์š”.โ€๋ผ๊ณ  ๋ช…์‹œํ•˜์„ธ์š”.

3) ํ”„๋กœํ•„ ์—…๋ฐ์ดํŠธ: ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ(NOT NULL)

์›์‹œ ์‹คํŒจ: null value in column "last_name" violates not-null constraint

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๊ฒƒ: โ€œ์„ฑ(Last name)์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.โ€

์ด๊ฒŒ ๋ฐ”๋กœ ์ข‹์€ ์ œ์•ฝ ์ฒ˜๋ฆฌ์˜ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค: ์‹œ์Šคํ…œ ์˜ค๋ฅ˜์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ณ  ์ผ๋ฐ˜ ํผ ํ”ผ๋“œ๋ฐฑ์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

์ง€์›ํŒ€์„ ๋•๋˜ ๊ธฐ์ˆ ์  ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์ „์ฒด ์˜ค๋ฅ˜๋Š” ๋กœ๊ทธ(๋˜๋Š” ๋‚ด๋ถ€ ์˜ค๋ฅ˜ ํŒจ๋„)์— ๋‚จ๊ธฐ์„ธ์š”: ์š”์ฒญ ID์™€ ์‚ฌ์šฉ์ž/์„ธ์…˜ ID, ์ œ์•ฝ๋ช…(๊ฐ€๋Šฅํ•˜๋ฉด), ํ…Œ์ด๋ธ”/ํ•„๋“œ, API ํŽ˜์ด๋กœ๋“œ(๋ฏผ๊ฐํ•œ ํ•„๋“œ๋Š” ๋งˆ์Šคํ‚น), ํƒ€์ž„์Šคํƒฌํ”„์™€ ์—”๋“œํฌ์ธํŠธ, ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค€ ๋ฉ”์‹œ์ง€๋ฅผ ํฌํ•จํ•˜์„ธ์š”.

์™ธ๋ž˜ ํ‚ค ์˜ค๋ฅ˜: ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ๋ณตํ•˜๋„๋ก ๋•๊ธฐ

Design constraints with confidence
Model your data in PostgreSQL and keep constraint rules clear as your schema changes.
Build now

์™ธ๋ž˜ ํ‚ค ์‹คํŒจ๋Š” ๋ณดํ†ต ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ํ•ญ๋ชฉ์ด ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํ—ˆ์šฉ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ํ˜„์žฌ ๊ทœ์น™๊ณผ ๋งž์ง€ ์•Š๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ์‹คํŒจ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ๋ฟ ์•„๋‹ˆ๋ผ ๋ช…ํ™•ํ•œ ๋‹ค์Œ ๋™์ž‘์„ ์ œ์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์™ธ๋ž˜ ํ‚ค ์˜ค๋ฅ˜๋Š” ์ฐธ์กฐํ•˜๋Š” ์„ ํƒ๊ธฐ ํ•œ ํ•„๋“œ์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค(๊ณ ๊ฐ, ํ”„๋กœ์ ํŠธ, ๋‹ด๋‹น์ž ๋“ฑ). ๋ฉ”์‹œ์ง€๋Š” ๋‚ด๋ถ€ ID๋‚˜ ํ…Œ์ด๋ธ” ์ด๋ฆ„ ๋Œ€์‹  ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์‹ํ•˜๋Š” ๋Œ€์ƒ์„ ์ด๋ฆ„์œผ๋กœ ๋ถˆ๋Ÿฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. โ€œ๊ณ ๊ฐ์ด ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹คโ€๋Š” ์œ ์šฉํ•˜์ง€๋งŒ โ€œFK_orders_customer_id violated (customer_id=42)โ€๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŠผํŠผํ•œ ๋ณต๊ตฌ ํŒจํ„ด์€ ์ด ์˜ค๋ฅ˜๋ฅผ ์˜ค๋ž˜๋œ ์„ ํƒ(stale selection)์œผ๋กœ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์ตœ์‹  ๋ชฉ๋ก์—์„œ ๋‹ค์‹œ ์„ ํƒํ•˜๋„๋ก ์œ ๋„(๋“œ๋กญ๋‹ค์šด ์ƒˆ๋กœ๊ณ ์นจ ๋˜๋Š” ๊ฒ€์ƒ‰ ์„ ํƒ๊ธฐ ์—ด๊ธฐ)ํ•˜์„ธ์š”. ๋ ˆ์ฝ”๋“œ๊ฐ€ ์‚ญ์ œ๋˜๊ฑฐ๋‚˜ ๋ณด๊ด€(archived)๋œ ๊ฒฝ์šฐ ๋ช…ํ™•ํžˆ ํ‘œ์‹œํ•˜๊ณ  ํ™œ์„ฑ ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜๋„๋ก ์•ˆ๋‚ดํ•˜์„ธ์š”. ์‚ฌ์šฉ์ž๊ฐ€ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์žƒ์—ˆ๋‹ค๋ฉด โ€œ์ด ํ•ญ๋ชฉ์„ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹คโ€๋ผ๊ณ  ์•Œ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ํ•ญ๋ชฉ์„ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜๋ผ๊ณ  ์•ˆ๋‚ดํ•˜์„ธ์š”. ๊ด€๋ จ ๋ ˆ์ฝ”๋“œ ์ƒ์„ฑ์„ ์ •์ƒ์ ์ธ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ํ—ˆ์šฉํ•œ๋‹ค๋ฉด ๋ฐ˜๋ณต ์žฌ์‹œ๋„๋ฅผ ๊ฐ•์š”ํ•˜๊ธฐ๋ณด๋‹ค โ€œ์ƒˆ ๊ณ ๊ฐ ๋งŒ๋“ค๊ธฐโ€ ๊ฐ™์€ ์˜ต์…˜์„ ์ œ๊ณตํ•˜์„ธ์š”.

์‚ญ์ œ๋˜๊ฑฐ๋‚˜ ๋ณด๊ด€๋œ ๋ ˆ์ฝ”๋“œ๋Š” ํ”ํ•œ ํ•จ์ •์ž…๋‹ˆ๋‹ค. UI์—์„œ ๋น„ํ™œ์„ฑ ํ•ญ๋ชฉ์„ ๋ฌธ๋งฅ์ƒ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค๋ฉด(์˜ˆ: Archived๋กœ ๋ผ๋ฒจ) ์„ ํƒ์„ ๋ง‰์•„ ์ด ์‹คํŒจ๋ฅผ ๋ฏธ์—ฐ์— ๋ฐฉ์ง€ํ•˜์„ธ์š”. ๊ทธ๋ž˜๋„ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ๋Š” ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋•Œ๋กœ ์™ธ๋ž˜ ํ‚ค ์‹คํŒจ๋Š” ํŠน์ • ํ•„๋“œ๋กœ ์ •ํ™•ํžˆ ๋งคํ•‘ํ•  ์ˆ˜ ์—†์„ ๋•Œ ํผ ์ˆ˜์ค€ ์˜ค๋ฅ˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ฐธ์กฐ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผ์ผฐ๋Š”์ง€ ํ™•์‹คํžˆ ์•Œ ์ˆ˜ ์—†๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ์ฐธ์กฐ๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ๊ถŒํ•œ ๋ฌธ์ œ๊ฐ€ ์ „์ฒด ๋™์ž‘์— ๊ฑธ์ณ ์žˆ๋‹ค๋ฉด ํผ ์ˆ˜์ค€์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์„ธ์š”.

NOT NULL๊ณผ ๊ฒ€์ฆ: ์˜ค๋ฅ˜๋ฅผ ์˜ˆ๋ฐฉํ•˜๋˜ ์ฒ˜๋ฆฌ๋„ ํ•˜๋ผ

One error format everywhere
Create a consistent error contract once and reuse it across web and native mobile apps.
Start building

NOT NULL ์‹คํŒจ๋Š” ์˜ˆ๋ฐฉํ•˜๊ธฐ ๊ฐ€์žฅ ์‰ฝ์ง€๋งŒ ๋น ์ ธ๋‚˜๊ฐ€๋ฉด ๊ฐ€์žฅ ์„ฑ๊ฐ€์‹  ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ํ•„์ˆ˜ ํ•„๋“œ๋ฅผ ๋น„์›Œ๋‘๊ณ  โ€œ์š”์ฒญ ์‹คํŒจโ€๋ฅผ ๋ณด๋Š” ์‚ฌ์šฉ์ž๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ UI ์—…๋ฌด๋ฅผ ๋Œ€์‹ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋А๋‚๋‹ˆ๋‹ค. ์ข‹์€ ์ œ์•ฝ ์˜ค๋ฅ˜ UX๋Š” UI์—์„œ ๋ช…๋ฐฑํ•œ ๊ฒฝ์šฐ๋ฅผ ๋ง‰๊ณ , ๊ทธ๋ž˜๋„ ๋†“์น˜๋ฉด API๊ฐ€ ๋ช…ํ™•ํ•œ ํ•„๋“œ ์ˆ˜์ค€ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € ํผ์—์„œ ์กฐ๊ธฐ ๊ฒ€์‚ฌ๋ฅผ ํ•˜์„ธ์š”. ํ•„์ˆ˜ ํ•„๋“œ๋Š” ์ž…๋ ฅ ๊ทผ์ฒ˜์— ํ‘œ์‹œํ•˜๊ณ (์ผ๋ฐ˜ ๋ฐฐ๋„ˆ๊ฐ€ ์•„๋‹ˆ๋ผ), ์งง์€ ํžŒํŠธ(์˜ˆ: โ€œ์˜์ˆ˜์ฆ ๋ฐœํ–‰์— ํ•„์š”ํ•จโ€)๋ฅผ ์ œ๊ณตํ•˜๋ฉด ๋นจ๊ฐ„ ๋ณ„ํ‘œ๋งŒ ์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•„๋“œ๊ฐ€ ์กฐ๊ฑด๋ถ€๋กœ ํ•„์ˆ˜๋ผ๋ฉด(์˜ˆ: โ€œ๊ณ„์ • ์œ ํ˜• = ์‚ฌ์—…์žโ€์ผ ๋•Œ๋งŒ ํšŒ์‚ฌ๋ช… ํ•„์š”) ๊ทธ ๊ทœ์น™์ด ๊ด€๋ จ ์‹œ์ ์— ๋ณด์ด๋„๋ก ํ•˜์„ธ์š”.

UI ๊ฒ€์ฆ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๊ตฌ๋ฒ„์ „ ์•ฑ, ๋ถˆ์•ˆ์ •ํ•œ ๋„คํŠธ์›Œํฌ, ๋Œ€๋Ÿ‰ ์—…๋กœ๋“œ, ์ž๋™ํ™”๋กœ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API์—๋„ ๊ฐ™์€ ๊ทœ์น™์„ ์ ์šฉํ•ด ์™•๋ณต์„ ๋‚ญ๋น„ํ•˜์ง€ ์•Š๋„๋ก ํ•˜์„ธ์š”.

๋ฌธ๊ตฌ๋ฅผ ์•ฑ ์ „์ฒด์—์„œ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜์„ธ์š”. ๋ˆ„๋ฝ ๊ฐ’์€ โ€œํ•„์ˆ˜์ž…๋‹ˆ๋‹ค(Required)โ€, ๊ธธ์ด ์ดˆ๊ณผ๋Š” โ€œ๋„ˆ๋ฌด ๊น€(์ตœ๋Œ€ 50์ž)โ€, ํ˜•์‹ ์˜ค๋ฅ˜๋Š” โ€œํ˜•์‹์ด ์ž˜๋ชป๋จ(์˜ˆ: [email protected])โ€, ํƒ€์ž… ๋ฌธ์ œ๋Š” โ€œ์ˆซ์ž์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹คโ€์ฒ˜๋Ÿผ ๊ณ ์ • ํ‘œํ˜„์„ ์“ฐ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค.

๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ(PATCH)๋Š” NOT NULL์—์„œ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ํ•„๋“œ๊ฐ€ ์š”์ฒญ์—์„œ ๋น ์ ธ๋„ ์‹คํŒจํ•˜๋ฉด ์•ˆ ๋˜์ง€๋งŒ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ null์ด๋‚˜ ๋นˆ๊ฐ’์œผ๋กœ ๋ณด๋ƒˆ๋‹ค๋ฉด ์‹คํŒจํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ทœ์น™์„ ํ•œ ๋ฒˆ ์ •ํ•ด ๋ฌธ์„œํ™”ํ•˜๊ณ  ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉํ•˜์„ธ์š”.

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

โ€œ์š”์ฒญ ์‹คํŒจโ€๋กœ ๋˜๋Œ์•„๊ฐ€๊ฒŒ ํ•˜๋Š” ํ”ํ•œ ์‹ค์ˆ˜๋“ค

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

ํ”ํ•œ ์‹ค์ˆ˜ ์ค‘ ํ•˜๋‚˜๋Š” ์›์‹œ DB ํ…์ŠคํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. duplicate key value violates unique constraint ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋Š” ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋„ ์‹œ์Šคํ…œ ๋ถ•๊ดด์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ฌด์„œ์šด ํ…์ŠคํŠธ๋ฅผ ๋ณต์‚ฌํ•ด ์ง€์›์— ๋ณด๋‚ด๊ณ  ์‹ค์ œ๋กœ ํ•„๋“œ๋ฅผ ๊ณ ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํ•จ์ •์€ ๋ฌธ์ž์—ด ๋งค์นญ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜ Postgres๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ฑฐ๋‚˜ ์ œ์•ฝ๋ช…์„ ๋ฐ”๊พธ๋ฉด ๋งคํ•‘์ด ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋˜๊ณ  โ€œ์ด๋ฉ”์ผ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘โ€ ๋งคํ•‘์ด ์กฐ์šฉํžˆ ๊นจ์ง‘๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ์—๋Ÿฌ ์ฝ”๋“œ์™€ UI๊ฐ€ ์ดํ•ดํ•˜๋Š” ํ•„๋“œ๋ช…์„ ํฌํ•จํ•˜๋Š” ๋ฐฉ์‹์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์€ ํ•„๋“œ ๋งคํ•‘์„ ์ƒ๊ฐ๋ณด๋‹ค ์ž์ฃผ ๊นจ๋œจ๋ฆฝ๋‹ˆ๋‹ค. email์„ primary_email๋กœ ๋ฐ”๊พธ๋ฉด ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋  ์ž๋ฆฌ๋ฅผ ์žƒ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งคํ•‘์„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ๊ฐ™์€ ๋ณ€๊ฒฝ ์„ธํŠธ์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ค๊ณ , ํ•„๋“œ ํ‚ค๊ฐ€ ์•Œ๋ ค์ง€์ง€ ์•Š์•˜์„ ๋•Œ ํ…Œ์ŠคํŠธ์—์„œ ์‹คํŒจํ•˜๊ฒŒ ํ•˜์„ธ์š”.

ํฐ UX ํŒŒ๊ดด์ž๋Š” ๋ชจ๋“  ์ œ์•ฝ ์‹คํŒจ๋ฅผ ๋ณธ๋ฌธ ์—†๋Š” HTTP 500์œผ๋กœ ๋Œ๋ ค๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด UI๋Š” โ€œ์„œ๋ฒ„ ์˜ค๋ฅ˜โ€๋ผ๊ณ ๋งŒ ํŒ๋‹จํ•ด ํ•„๋“œ ํžŒํŠธ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ œ์•ฝ ์‹คํŒจ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ์น  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฒ€์ฆ ์Šคํƒ€์ผ์˜ ์‘๋‹ต๊ณผ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์„ธ์š”.

์ฃผ์˜ํ•  ํŒจํ„ด๋“ค:

  • ๊ณ ์œ  ์ด๋ฉ”์ผ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ณ„์ • ์กด์žฌ๋ฅผ ํ™•์ธ์‹œ์ผœ ์ฃผ๋Š” ๊ฒฝ์šฐ(๊ฐ€์ž… ํ๋ฆ„์—์„œ๋Š” ์ค‘๋ฆฝ์  ๋ฌธ๊ตฌ ์‚ฌ์šฉ)
  • โ€œํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์˜ค๋ฅ˜๋งŒโ€ ์ฒ˜๋ฆฌํ•ด ๋‘ ๋ฒˆ์งธ ๊นจ์ง„ ํ•„๋“œ๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒฝ์šฐ
  • ๋’ค๋กœ/๋‹ค์Œ ํด๋ฆญ์œผ๋กœ ๋‹ค๋‹จ๊ณ„ ํผ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ
  • ์žฌ์‹œ๋„๊ฐ€ ์˜ค๋ž˜๋œ ๊ฐ’์„ ์ œ์ถœํ•ด ์˜ฌ๋ฐ”๋ฅธ ํ•„๋“œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ๊ฒฝ์šฐ
  • ๋กœ๊น…์ด ์ œ์•ฝ๋ช…์ด๋‚˜ ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ๋ฒ„๋ ค ๋ฒ„๊ทธ ์ถ”์ ์„ ์–ด๋ ต๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ

์˜ˆ์ปจ๋Œ€ ๊ฐ€์ž… ํผ์ด โ€œ์ด๋ฉ”์ผ์ด ์ด๋ฏธ ์กด์žฌํ•จโ€์ด๋ผ๊ณ  ํ•˜๋ฉด ๊ณ„์ • ์กด์žฌ๋ฅผ ์œ ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฉ”์ผ ํ•„๋“œ์—๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ถ™์ด๋˜ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” โ€œ์ด๋ฉ”์ผ์„ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ์ธํ•ด ๋ณด์„ธ์š”โ€์ฒ˜๋Ÿผ ์ค‘๋ฆฝ์ ์ธ ๋ฌธ๊ตฌ๋ฅผ ์“ฐ๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ์ „ ๋น ๋ฅธ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

Map constraints to fields
Use visual logic to map constraint names to UI fields without hand-coding every form.
Try AppMaster

๋ฐฐํฌ ์ „์—๋Š” ์ œ์•ฝ ์‹คํŒจ๊ฐ€ ์œ ์šฉํ•œ ํžŒํŠธ๊ฐ€ ๋ ์ง€ ๋ง‰๋‹ค๋ฅธ ๊ธธ์ด ๋ ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์ž‘์€ ๋””ํ…Œ์ผ๋“ค์„ ์ ๊ฒ€ํ•˜์„ธ์š”.

API ์‘๋‹ต: UI๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€?

๊ฐ ๊ฒ€์ฆ ์Šคํƒ€์ผ ์‹คํŒจ๊ฐ€ ํŠน์ • ์ž…๋ ฅ์„ ๊ฐ€๋ฆฌํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์„ธ์š”. ๊ฐ ์˜ค๋ฅ˜์— field, ์•ˆ์ •์ ์ธ code, ์‚ฌ๋žŒ์ด ์ฝ์„ message๋ฅผ ํฌํ•จํ•˜์„ธ์š”. ๊ณ ์œ , ์™ธ๋ž˜ ํ‚ค, NOT NULL, ์ฒดํฌ ๊ฐ™์€ ์ผ๋ฐ˜ DB ์‚ฌ๋ก€๋ฅผ ์ปค๋ฒ„ํ•˜๊ณ  ๊ธฐ์ˆ ์  ์„ธ๋ถ€ ์ •๋ณด๋Š” ๋กœ๊ทธ์—๋งŒ ๋‚จ๊ธฐ์„ธ์š”.

UI ๋™์ž‘: ์‚ฌ์šฉ์ž๊ฐ€ ํšŒ๋ณตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•๋Š”๊ฐ€?

์™„๋ฒฝํ•œ ๋ฉ”์‹œ์ง€๋„ ํผ์ด ์‚ฌ์šฉ์ž๋ฅผ ๋ฐฉํ•ดํ•˜๋ฉด ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฒซ ์‹คํŒจ ํ•„๋“œ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถ”๊ณ  ํ•„์š”ํ•˜๋ฉด ์Šคํฌ๋กค๋กœ ๋ณด์ด๊ฒŒ ํ•˜์„ธ์š”. ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์€ ๋ณด์กดํ•˜์„ธ์š”(ํŠนํžˆ ์—ฌ๋Ÿฌ ํ•„๋“œ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ๋•Œ). ํ•„๋“œ ์ˆ˜์ค€ ์˜ค๋ฅ˜๋ฅผ ์šฐ์„  ๋ณด์—ฌ์ฃผ๊ณ  ์š”์•ฝ ๋ฐฐ๋„ˆ๋Š” ๋ณด์กฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.

๋กœ๊น…๊ณผ ํ…Œ์ŠคํŠธ: ํšŒ๊ท€๋ฅผ ์žก๋Š”๊ฐ€?

์ œ์•ฝ ์ฒ˜๋ฆฌ๋Š” ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ๋•Œ ์กฐ์šฉํžˆ ๊นจ์ง€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. DB ์˜ค๋ฅ˜(์ œ์•ฝ๋ช…, ํ…Œ์ด๋ธ”, ์ž‘์—…, ์š”์ฒญ ID)๋ฅผ ๋‚ด๋ถ€ ๋กœ๊ทธ์— ๋‚จ๊ธฐ๋˜ ์ ˆ๋Œ€ ์›์‹œ ํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ์ง€ ๋งˆ์„ธ์š”. ๊ฐ ์ œ์•ฝ ์œ ํ˜•๋ณ„๋กœ ์ตœ์†Œ ํ•˜๋‚˜์”ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋งคํ•‘์ด ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์ด๋‚˜ ๋“œ๋ผ์ด๋ฒ„ ์—…๋ฐ์ดํŠธ์—๋„ ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€๋˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

๋‹ค์Œ ๋‹จ๊ณ„: ์•ฑ ์ „๋ฐ˜์— ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉํ•˜๊ธฐ

๋Œ€๋ถ€๋ถ„ ํŒ€์€ ์ œ์•ฝ ์˜ค๋ฅ˜๋ฅผ ํ™”๋ฉด ๋‹จ์œ„๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค. ๊ทธ๊ฑด ๋„์›€์ด ๋˜์ง€๋งŒ ์‚ฌ์šฉ์ž๋Š” ๊ฒฉ์ฐจ๋ฅผ ๋А๋‚๋‹ˆ๋‹ค: ํ•œ ํผ์€ ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋‹ค๋ฅธ ํผ์€ ์—ฌ์ „ํžˆ โ€œ์š”์ฒญ ์‹คํŒจโ€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ผ๊ด€์„ฑ์ด ํŒจ์น˜๋ฅผ ํŒจํ„ด์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

๋จผ์ € ์•„ํ”ˆ ๊ณณ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์„ธ์š”. ์ผ์ฃผ์ผ ์น˜ ๋กœ๊ทธ๋‚˜ ์ง€์› ํ‹ฐ์ผ“์„ ์‚ดํŽด๋ณด๊ณ  ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์ œ์•ฝ ๋ช‡ ๊ฐ€์ง€๋ฅผ ๊ณจ๋ผ ์šฐ์„  ์นœ์ ˆํ•œ ํ•„๋“œ ์ˆ˜์ค€ ๋ฉ”์‹œ์ง€๋ฅผ ์ ์šฉํ•˜์„ธ์š”.

์˜ค๋ฅ˜ ๋ฒˆ์—ญ์„ ์ž‘์€ ์ œํ’ˆ ๊ธฐ๋Šฅ์œผ๋กœ ์ทจ๊ธ‰ํ•˜์„ธ์š”. ์•ฑ ์ „์ฒด์—์„œ ์“ฐ๋Š” ํ•˜๋‚˜์˜ ๊ณต์œ  ๋งคํ•‘์„ ์œ ์ง€ํ•˜์„ธ์š”: ์ œ์•ฝ๋ช…(๋˜๋Š” ์ฝ”๋“œ) -> ํ•„๋“œ ์ด๋ฆ„ -> ๋ฉ”์‹œ์ง€ -> ๋ณต๊ตฌ ํžŒํŠธ. ๋ฉ”์‹œ์ง€๋Š” ํ‰์ดํ•œ ์–ธ์–ด๋กœ, ํžŒํŠธ๋Š” ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ์„ธ์š”.

๋ฐ”์œ ์ œํ’ˆ ์‚ฌ์ดํด์— ๋งž๋Š” ๊ฐ€๋ฒผ์šด ๋ฐฐํฌ ๊ณ„ํš:

  • ์‚ฌ์šฉ์ž๋“ค์ด ์ž์ฃผ ๊ฒช๋Š” 5๊ฐ€์ง€ ์ œ์•ฝ์„ ์‹๋ณ„ํ•˜๊ณ  ๋ณด์—ฌ์ค„ ์ •ํ™•ํ•œ ๋ฌธ๊ตฌ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”.
  • ๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ชจ๋“  ์—”๋“œํฌ์ธํŠธ์—์„œ ์‚ฌ์šฉํ•˜์„ธ์š”.
  • ํผ์ด ์˜ค๋ฅ˜๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์„ ํ‘œ์ค€ํ™”ํ•˜์„ธ์š”(๊ฐ™์€ ์œ„์น˜, ๊ฐ™์€ ์–ด์กฐ, ๊ฐ™์€ ํฌ์ปค์Šค ๋™์ž‘).
  • ๋น„๊ธฐ์ˆ  ๋™๋ฃŒ์™€ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฒ€ํ† ํ•˜๊ณ  โ€œ๋‹ค์Œ์— ๋ฌด์—‡์„ ํ•˜๊ฒ ๋Š”๊ฐ€?โ€๋ผ๊ณ  ๋ฌผ์–ด๋ณด์„ธ์š”.
  • ๊ฐ ํผ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด ์˜ฌ๋ฐ”๋ฅธ ํ•„๋“œ๊ฐ€ ๊ฐ•์กฐ๋˜๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ์ฝ๊ธฐ ์‰ฌ์šด์ง€ ํ™•์ธํ•˜์„ธ์š”.

์†์ˆ˜ ๋ชจ๋“  ํ™”๋ฉด์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ๋„ ์ด ์ผ๊ด€๋œ ๋™์ž‘์„ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด AppMaster(appmaster.io)์ด ๋ฐฑ์—”๋“œ API์™€ ์ƒ์„ฑ๋œ ์›น/๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๊ตฌ์กฐํ™”๋œ ์—๋Ÿฌ ํ˜•์‹์„ ํด๋ผ์ด์–ธํŠธ ์ „๋ฐ˜์—์„œ ์žฌ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์ด ๋ฐ”๋€Œ์–ด๋„ ํ•„๋“œ ์ˆ˜์ค€ ํ”ผ๋“œ๋ฐฑ์ด ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

ํŒ€์„ ์œ„ํ•œ ์งง์€ โ€œ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์Šคํƒ€์ผโ€ ๋…ธํŠธ๋„ ์ž‘์„ฑํ•˜์„ธ์š”. ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•˜์„ธ์š”: ์–ด๋–ค ๋‹จ์–ด๋ฅผ ํ”ผํ• ์ง€(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์šฉ์–ด), ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ๋ฉ”์‹œ์ง€์— ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•  ๊ฒƒ(๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋Š”์ง€, ๋‹ค์Œ์— ๋ฌด์—‡์„ ํ• ์ง€).

์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ

Why do database constraint errors feel so frustrating to users?

์ผ๋ฐ˜์ ์ธ ์‹œ์Šคํ…œ ์˜ค๋ฅ˜์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š๊ฒŒ ํ•˜์„ธ์š”. ์ˆ˜์ •ํ•ด์•ผ ํ•  ์ •ํ™•ํ•œ ํ•„๋“œ ์˜†์— ์งง์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์€ ์œ ์ง€ํ•˜๋ฉฐ ๋‹ค์Œ ๋‹จ๊ณ„(๋ฌด์—‡์„ ํ•˜๋ฉด ๋˜๋Š”์ง€)๋ฅผ ํ‰์ดํ•œ ์–ธ์–ด๋กœ ์•Œ๋ ค์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Whatโ€™s the difference between a field-level error and a generic โ€œrequest failedโ€ message?

ํ•„๋“œ ์ˆ˜์ค€ ์˜ค๋ฅ˜๋Š” ํŠน์ • ์ž…๋ ฅ์„ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ ๊ฑฐ๊ธฐ์„œ ๋ฐ”๋กœ ๋ฌด์—‡์„ ๊ณ ์ณ์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ค๋‹ˆ๋‹ค(์˜ˆ: โ€œ์ด ์ด๋ฉ”์ผ์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹คโ€). ๋ฐ˜๋ฉด ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜๋Š” ๋ฌด์—‡์„ ๋ฐ”๊ฟ”์•ผ ํ• ์ง€ ์•Œ๋ ค์ฃผ์ง€ ์•Š์•„ ์‚ฌ์šฉ์ž๊ฐ€ ์ถ”์ธกํ•˜๊ฑฐ๋‚˜ ์žฌ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์ง€์›์— ๋ฌธ์˜ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

How do I reliably detect which constraint failed?

๊ฐ€๋Šฅํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„์˜ ์•ˆ์ •์ ์ธ ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ด๋ฅผ ๊ณ ์œ (unique), ์™ธ๋ž˜ ํ‚ค(foreign key), ํ•„์ˆ˜(required), ๋ฒ”์œ„(check) ๊ฐ™์€ ์‚ฌ์šฉ์ž ์นœํ™”์  ์œ ํ˜•์œผ๋กœ ๋งคํ•‘ํ•˜์„ธ์š”. ์›์‹œ DB ํ…์ŠคํŠธ๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ๋ฐฉ์‹์€ ๋“œ๋ผ์ด๋ฒ„๋‚˜ ๋ฒ„์ „์ด ๋ฐ”๋€Œ๋ฉด ๊นจ์ง‘๋‹ˆ๋‹ค.

How do I map a constraint name to the correct form field?

์Šคํ‚ค๋งˆ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ฝ”๋“œ ๊ทผ์ฒ˜์— ์ œ์•ฝ๋ช…โ†’UI ํ•„๋“œ ํ‚ค ๋งคํ•‘์„ ๋‘์„ธ์š”. ์˜ˆ: users_email_key โ†’ email. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด UI๊ฐ€ ์ถ”์ธกํ•˜์ง€ ์•Š๊ณ  ์ •ํ™•ํ•œ ์ž…๋ ฅ์„ ๊ฐ•์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

What should I say for a unique constraint error (like duplicate email)?

๊ธฐ๋ณธ ๋ฌธ๊ตฌ๋Š” โ€œ์ด ๊ฐ’์€ ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹คโ€์ฒ˜๋Ÿผ ํ•˜๊ณ , ํ๋ฆ„์— ๋”ฐ๋ผ โ€œ๋‹ค๋ฅธ ๊ฐ’์„ ์‹œ๋„ํ•˜์„ธ์š”โ€ ๋˜๋Š” โ€œ๋กœ๊ทธ์ธํ•˜์„ธ์š”โ€ ๊ฐ™์€ ๋‹ค์Œ ๋™์ž‘์„ ํ•จ๊ป˜ ์ œ์‹œํ•˜์„ธ์š”. ๊ฐ€์ž…์ด๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ •์—์„œ๋Š” ๊ณ„์ • ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๋…ธ์ถœํ•˜์ง€ ์•Š๋„๋ก ์ค‘๋ฆฝ์ ์ธ ๋ฌธ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

How should I handle foreign key errors without confusing people?

์‚ฌ์šฉ์ž๊ฐ€ ์ธ์‹ํ•˜๋Š” ํ•ญ๋ชฉ ์ด๋ฆ„์œผ๋กœ ์„ค๋ช…ํ•˜์„ธ์š”: โ€œํ•ด๋‹น ๊ณ ๊ฐ์ด ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ณ ๊ฐ์„ ์„ ํƒํ•˜์„ธ์š”.โ€ ์„ ํƒ์ง€๋ฅผ ์ƒˆ๋กœ ๊ณ ์น˜ํ•˜๊ฑฐ๋‚˜, ์‚ฌ์šฉ ๊ถŒํ•œ์ด ์—†์„ ๊ฒฝ์šฐ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜๋ผ๊ณ  ์•ˆ๋‚ดํ•˜๊ฑฐ๋‚˜, ๊ด€๋ จ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฒฝ๋กœ๋ฅผ ๋ฐ”๋กœ ์ œ๊ณตํ•˜์„ธ์š”.

If my UI validates required fields, why do NOT NULL errors still happen?

UI์—์„œ ํ•„์ˆ˜ ์ž…๋ ฅ์„ ํ‘œ์‹œํ•˜๊ณ  ์ „์†ก ์ „์— ๊ฒ€์ฆํ•˜์„ธ์š”. ํ•˜์ง€๋งŒ ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ, ๊ตฌ๋ฒ„์ „ ์•ฑ, ๋Œ€๋Ÿ‰ ์—…๋กœ๋“œ ๋“ฑ์œผ๋กœ UI ๊ฒ€์ฆ์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ, API์™€ DB ๋ ˆ์ด์–ด์—์„œ๋„ ๊ฐ™์€ ๊ทœ์น™์„ ๊ฒ€์ฆํ•˜๊ณ  ์ตœ์ข…์ ์œผ๋กœ NOT NULL ์˜ค๋ฅ˜๋ฅผ ์žก์•„ ์ ์ ˆํ•œ ํ•„๋“œ ์˜ค๋ฅ˜๋กœ ๋งคํ•‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

How do I handle multiple constraint errors from one Save?

์—๋Ÿฌ ๋ฐฐ์—ด๋กœ ๊ฐ ์˜ค๋ฅ˜์— field, ์•ˆ์ •์  ์ฝ”๋“œ(code), ์งง์€ ๋ฉ”์‹œ์ง€๋ฅผ ํฌํ•จํ•ด ๋ฐ˜ํ™˜ํ•˜์„ธ์š”. ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ์‹คํŒจ ํ•„๋“œ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถ”๋˜ ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€๋„ ํ•จ๊ป˜ ๋ณด์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

What should an API error response include so the UI can render it correctly?

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ ๋ฉ”์‹œ์ง€์™€ ๋‚ด๋ถ€ ๋กœ๊น…์šฉ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋ถ„๋ฆฌํ•˜์„ธ์š”. ์‚ฌ์šฉ์ž์šฉ ๋ฉ”์‹œ์ง€์™€ ๋‚ด๋ถ€์šฉ ์„ธ๋ถ€(์ œ์•ฝ๋ช…, ์š”์ฒญ ID ๋“ฑ)๋ฅผ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ํ•˜๋˜, ์›์‹œ SQL ์—๋Ÿฌ ํ…์ŠคํŠธ๋Š” ์ ˆ๋Œ€ ๋…ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”.

How can I keep constraint error handling consistent across web and mobile apps?

๋ฐฑ์—”๋“œ์—์„œ ํ•œ ๊ตฐ๋ฐ์„œ ๋ฒˆ์—ญ์„ ์ค‘์•™ํ™”ํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์—๋Ÿฌ ํ˜•์‹์„ ๋ฐ˜ํ™˜ํ•˜์„ธ์š”. AppMaster๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผํ•œ ๊ตฌ์กฐํ™”๋œ ์—๋Ÿฌ ๊ณ„์•ฝ์„ ์›น๊ณผ ๋ชจ๋ฐ”์ผ์— ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋ฉ”์‹œ์ง€๊ฐ€ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์‰ฌ์šด ์‹œ์ž‘
๋ฉ‹์ง„๋งŒ๋“ค๊ธฐ

๋ฌด๋ฃŒ ์š”๊ธˆ์ œ๋กœ AppMaster๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”.
์ค€๋น„๊ฐ€ ๋˜๋ฉด ์ ์ ˆํ•œ ๊ตฌ๋…์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๋‹ค
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ œ์•ฝ ์˜ค๋ฅ˜ UX: ์‹คํŒจ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฉ”์‹œ์ง€๋กœ ๋ฐ”๊พธ๊ธฐ | AppMaster