generated from Chuseok22/chuseok22-github-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
enhancement๊ธฐ๋ฅ ๊ฐ์ /ํฅ์ (Enhancement)๊ธฐ๋ฅ ๊ฐ์ /ํฅ์ (Enhancement)์์
์ ์์
์์ ์ ์ค๋น ์ํ์์
์์ ์ ์ค๋น ์ํ
Description
๐ ํ์ฌ ๋ฌธ์ ์
ํ์ฌ ์ฅ๋ฐ๊ตฌ๋ ๋ฉ๋ด ์ถ๊ฐ API๋ quantity๊ฐ โํด๋น ๋ฉ๋ด์ ์ต์ข
(๋์ ) ์๋โ ์ผ๋ก ๋์ํฉ๋๋ค.
- ์์ฒญ ํ๋ผ๋ฏธํฐ
menuId(Long, required): ์ฅ๋ฐ๊ตฌ๋์ ๋ด์ ๋ฉ๋ด IDquantity(int, required)- 1 ์ด์: ํด๋น ์๋์ผ๋ก ์ฅ๋ฐ๊ตฌ๋์ ์ถ๊ฐ ๋๋ ์์ (= ์ต์ข ์๋ SET)
- 0: ํด๋น ๋ฉ๋ด๋ฅผ ์ฅ๋ฐ๊ตฌ๋์์ ์ญ์
- ์๋ต ๋ฐ์ดํฐ
cartId(Long): ์ฅ๋ฐ๊ตฌ๋ IDitems(List): ์ฅ๋ฐ๊ตฌ๋์ ๋ด๊ธด ๋ฉ๋ด ๋ชฉ๋กtotalPrice(int): ์ฅ๋ฐ๊ตฌ๋ ์ ์ฒด ๊ธ์ก
- ํน์ง
quantity=0์ ๋ฌ ์ ํด๋น ๋ฉ๋ด ์ญ์ - ์ฅ๋ฐ๊ตฌ๋๊ฐ ๋น์์ง๋ฉด ์ฅ๋ฐ๊ตฌ๋ ์ํฐํฐ ์๋ ์ญ์ (์ด ๊ฒฝ์ฐ ์๋ต์ cartId๊ฐ ํฌํจ๋์ง ์์ ์ ์์)
์ด ๊ตฌ์กฐ์์๋ โ์ถ๊ฐํ๊ธฐ(+N)โ UX๋ฅผ ๊ตฌํํ ๋ ํ๋ก ํธ์์
- ํ์ฌ ์๋ ํ์ (์กฐํ/์ํ ๋ณด์ )
- ์ถ๊ฐํ ์๋ ์ ๋ ฅ
- ์ต์ข
์๋ ๊ณ์ฐ(ํ์ฌ + ์ถ๊ฐ) ํ
quantity๋ก ์ ์ก
์ ์ํํด์ผ ํฉ๋๋ค.
๋ฌธ์ ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
- ํ๋ก ํธ ๋ก์ง ๋ณต์ก๋ ์ฆ๊ฐ
- โ๋ด๊ธฐโ ๊ธฐ๋ฅ์ด ๋จ์ํ +N์ ์๋ฏธํจ์๋, ํญ์ ํ์ฌ ์๋์ ์๊ณ ์์ด์ผ ํ๋ฏ๋ก ๊ตฌํ/์ํ ๋๊ธฐํ ๋น์ฉ์ด ์ฆ๊ฐํฉ๋๋ค.
- ๋์์ฑ(๋ฉํฐ ํญ/๋ฉํฐ ๋๋ฐ์ด์ค)์์ ๋ฎ์ด์ฐ๊ธฐ ์ํ
- ํด๋ผ์ด์ธํธ๊ฐ ์ค๋๋ โํ์ฌ ์๋โ์ ๊ธฐ์ค์ผ๋ก ์ต์ข ์๋์ ๊ณ์ฐํด ์ ์กํ๋ฉด, ์๋ฒ๊ฐ ์ด๋ฅผ ๊ทธ๋๋ก SETํ์ฌ ์๋์น ์๊ฒ ๋ฎ์ด์์ฐ๋(lost update) ์ํฉ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
- API ์๋ฏธ ํผํฉ์ผ๋ก ์ธํ ํ์ฅ์ฑ ์ ํ
- ๋จ์ผ
quantity๊ฐ์ผ๋ก โ์ถ๊ฐ/์ค์ /์ญ์ โ ์๋ฏธ๋ฅผ ๋ชจ๋ ํํํ๊ณ ์์ด ํด๋ผ์ด์ธํธ ์ธก ํด์ ํผ์ ์ด ๋ฐ์ํ๋ฉฐ, ํฅํ ๊ธฐ๋ฅ ํ์ฅ(๊ฐ์, ์ฆ๊ฐํ UX, ์ฌ์๋ ์์ ์ฑ)์๋ ์ ์ฝ์ด ์๊น๋๋ค.
๐ ๏ธ ํด๊ฒฐ ๋ฐฉ์ / ์ ์ ๊ธฐ๋ฅ
๋ณธ ์ด์์์๋ A์(๊ถ์ฅ)์ผ๋ก SET(์ต์ข
์๋ ์ค์ ) API ์ DELTA(์ฆ๊ฐ) API ๋ฅผ ๋ถ๋ฆฌ ์ ๊ณตํ๊ณ ,
DELTA API์ ๋ํด Idempotency-Key ๊ธฐ๋ฐ ๋ฉฑ๋ฑ์ฑ์ ์ง์ํฉ๋๋ค.
1) SET API(์ต์ข ์๋์ผ๋ก ๋ง์ถ๊ธฐ, ๋ฉฑ๋ฑ)
- ๋ชฉ์ : ์ฅ๋ฐ๊ตฌ๋ ํ๋ฉด์์ ์๋์ ์ง์ ํธ์ง(์คํ ํผ/์ง์ ์ ๋ ฅ)ํ๊ฑฐ๋, ํน์ ์๋์ผ๋ก โ์ ํํ ๋ง์ถ๋โ ๋์
- ํน์ง: ๋์ผ ์์ฒญ์ ์ฌ๋ฌ ๋ฒ ๋ณด๋ด๋ ๊ฒฐ๊ณผ๊ฐ ๋์ผ(๋ฉฑ๋ฑ)
- ๋์ ๊ท์น
quantity >= 1โ ํด๋น menu์ ์๋์ ํด๋น ๊ฐ์ผ๋ก ์ค์ quantity == 0โ ํด๋น menu ์ญ์ (์ญ์ ๋ ๋ณ๋ DELETE๋ก ๋ถ๋ฆฌ๋ ๊ฐ๋ฅํ๋, ๋ณธ ์ด์์์๋ ๊ธฐ์กด ์ ์ฑ ์ ์ง ๊ฐ๋ฅ)
2) DELTA API(์ถ๊ฐ/๊ฐ์, ์๋ฒ๊ฐ ๋์ ๊ณ์ฐ)
- ๋ชฉ์ : โ๋ด๊ธฐ(+N)โ, โํ ๊ฐ ๋(+1)โ, โํ ๊ฐ ๋นผ๊ธฐ(-1)โ ๊ฐ์ ์ฆ๊ฐํ UX๋ฅผ ๋จ์ํ๊ณ ์์ ํ๊ฒ ์ง์
- ํน์ง: ํด๋ผ์ด์ธํธ๋ โ์ถ๊ฐ/๊ฐ์ํ ์๋(delta)โ๋ง ์ ๋ฌ, ์๋ฒ๊ฐ ๊ธฐ์กด ์๋์ ์กฐํํด ๋์ ๋ฐ์
- ๋์ ๊ท์น
delta > 0โ ๊ธฐ์กด ์๋ + deltadelta < 0โ ๊ธฐ์กด ์๋ + delta (0 ์ดํ๊ฐ ๋๋ฉด ํด๋น menu ์ญ์ )- ๊ฒฐ๊ณผ์ ์ผ๋ก ์ฅ๋ฐ๊ตฌ๋๊ฐ ๋น๋ฉด cart ์ํฐํฐ ์ญ์ (๊ธฐ์กด ์ ์ฑ ๊ณผ ๋์ผ)
3) DELTA ๋ฉฑ๋ฑ์ฑ ๋ณด์ฅ: Idempotency-Key ์ง์(ํ์)
DELTA๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋น๋ฉฑ๋ฑ(์ค๋ณต ์์ฒญ ์ ์๋์ด ์ค๋ณต ์ฆ๊ฐ)ํ๋ฏ๋ก, ์๋ ์ ์ฑ ์ ๋ฐ๋์ ์ ์ฉํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ DELTA ์์ฒญ ์ ํค๋๋ก
Idempotency-Key(์์ฒญ ๊ณ ์ ํค)๋ฅผ ์ ์ก - ์๋ฒ๋
(userId(or cartOwner), menuId, idempotencyKey)๋จ์๋ก ์์ฒญ์ ๊ธฐ๋กํ๊ณ ,
๋์ผ ํค ์ฌ์์ฒญ ์ ์ต์ด ์ฒ๋ฆฌ ๊ฒฐ๊ณผ(์๋ต ๋ฐ๋)๋ฅผ ๊ทธ๋๋ก ์ฌ๋ฐํํ์ฌ ์ค๋ณต ๋ฐ์์ ๋ฐฉ์ง - ์ ์ฅ/๋ง๋ฃ ์ ์ฑ (TTL)์ ์ด์ ์ ์ฑ ์ ๋ฐ๋ผ ์ค์ (์: 24์๊ฐ ๋ฑ)ํ๋, ์ ํํ ๊ฐ์ ๋ณธ ์ด์์์ ํ์ ํ์
๊ธฐ๋ํจ๊ณผ
- ํ๋ก ํธ๋ โ์ถ๊ฐํ๊ธฐโ์์ ๋์ ์๋์ ๊ณ์ฐํ ํ์ ์์ด
delta๋ง ์ ์ก - ๋ชจ๋ฐ์ผ/๋ถ์์ ๋คํธ์ํฌ ํ๊ฒฝ์์ ์ฌ์๋/์ค๋ณต ํด๋ฆญ์ด ๋ฐ์ํด๋ ์ค๋ณต ๋ฐ์ ๋ฐฉ์ง
- โํธ์ง(SET)โ๊ณผ โ์ถ๊ฐ/๊ฐ์(DELTA)โ๊ฐ ๋ชฉ์ ๋ณ๋ก ๋ถ๋ฆฌ๋์ด API ์๋ฏธ๊ฐ ๋ช ํํด์ง
โ๏ธ ์์ ๋ด์ฉ
1) ๋ฐฑ์๋(JAVA + Spring Boot)
- SET API ์คํ ํ์ ๋ฐ ๊ตฌํ
- ์์ฒญ/์๋ต DTO ์ ์(
menuId,quantity) quantity==0์ญ์ ์ฒ๋ฆฌ ๋ฐ ๋ง์ง๋ง ์์ดํ ์ญ์ ์ cart ์ํฐํฐ ์ญ์ ์ฒ๋ฆฌ(๊ธฐ์กด ์ ์ฑ ์ค์)
- ์์ฒญ/์๋ต DTO ์ ์(
- DELTA API ์คํ ํ์ ๋ฐ ๊ตฌํ
- ์์ฒญ DTO ์ ์(
menuId,delta) delta < 0๊ฐ์ ์ 0 ์ดํ๊ฐ ๋๋ฉด cartItem ์ญ์ ์ฒ๋ฆฌ- ๊ฒฐ๊ณผ์ ์ผ๋ก cart๊ฐ ๋น๋ฉด cart ์ํฐํฐ ์ญ์ ์ฒ๋ฆฌ
- ์์ฒญ DTO ์ ์(
- DELTA ๋ฉฑ๋ฑ์ฑ(Idempotency-Key) ๊ตฌํ
- ํค๋
Idempotency-Keyํ์ฑ ๋ฐ ํ์ ์ฌ๋ถ ๊ฒฐ์ (DELTA์์๋ง ํ์ ๊ถ์ฅ) - ์ ์ฅ์ ์ค๊ณ
- key:
(userId, menuId, idempotencyKey)(์ ํํ ์๋ณ์ ๊ตฌ์ฑ์ ๋ณธ ์ด์์์ ํ์ ) - value: ์ฒ๋ฆฌ ๊ฒฐ๊ณผ(์ต์: ์ฒ๋ฆฌ ์๋ฃ ์ฌ๋ถ + ์๋ต ๋ฐ๋ ๋๋ ์ฌ๊ตฌ์ฑ ๊ฐ๋ฅํ ๋ฐ์ดํฐ)
- TTL/๋ง๋ฃ ์ ์ฑ ์ ์ฉ
- key:
- ๋์ผ ํค ์ฌ์์ฒญ ์ ์ต์ด ์๋ต ๋ฐํ
- ํค๋
- ์์ธ/์๋ต ๊ท์น ์ ๋ฆฌ
- menuId ์์, ์๋ชป๋ delta/quantity, ํ์ /์ฌ๊ณ ์ ์ฑ ๋ฑ(ํ์ฌ ์กด์ฌํ๋ ๊ท์น์ด ์๋ค๋ฉด ํด๋น ๊ท์น์ ๋ง์ถฐ ํ์ )
- cart ๋น์์ผ๋ก cart ์ํฐํฐ ์ญ์ ๋๋ ๊ฒฝ์ฐ ์๋ต(
cartIdnullable) ์ ์ฑ ๋ช ํํ
- ํ
์คํธ
- SET: ๋ฉฑ๋ฑ์ฑ(๋์ผ quantity ๋ฐ๋ณต), 0 ์ญ์ , ๋ง์ง๋ง ์ญ์ ์ cart ์ญ์
- DELTA: +N ๋์ , -1 ๊ฐ์, 0 ์ดํ ์ญ์ , ๋ง์ง๋ง ์ญ์ ์ cart ์ญ์
- DELTA: Idempotency-Key ๋์ผ ์์ฒญ ๋ฐ๋ณต ์ ์ค๋ณต ๋ฐ์ ์์ด ๋์ผ ์๋ต ๋ฐํ
- DELTA: ํค ๋ฏธ์ ๋ฌ/์๋ชป๋ ํค์ ์ฒ๋ฆฌ ๊ท์น ๊ฒ์ฆ
2) ํ๋ก ํธ(์น: TypeScript + Next.js App Router / ์ฑ: ReactNative + EXPO)
- โ๋ด๊ธฐ(+N)โ ๋ฐ ์ฆ๊ฐ ๋ฒํผ์ DELTA API ์ฌ์ฉ
- ํด๋ผ์ด์ธํธ๋ ์ถ๊ฐํ ๊ฐ์๋ง
delta๋ก ์ ๋ฌ - ์์ฒญ๋ง๋ค
Idempotency-Key์์ฑ/์ ์ก(์ค๋ณต ํด๋ฆญ/์ฌ์๋ ๋๋น)
- ํด๋ผ์ด์ธํธ๋ ์ถ๊ฐํ ๊ฐ์๋ง
- โ์๋ ์ง์ ํธ์ง(์ต์ข ์๋ ์ง์ )โ์ SET API ์ฌ์ฉ
- ์๋ต(items/totalPrice)์ ๊ธฐ์ค์ผ๋ก UI ์ํ๋ฅผ ํญ์ ๊ฐฑ์ (์๋ฒ ์๋ต์ ์์ค ์ค๋ธ ํธ๋ฃจ์ค๋ก)
- cart๊ฐ ๋น์ด cartId๊ฐ ๋๋ฝ๋ ์ ์๋ ์ผ์ด์ค ์ฒ๋ฆฌ(์๋ต items ๊ธฐ์ค์ผ๋ก empty ์ํ ์ฒ๋ฆฌ)
3) ๋ฌธ์ํ/์คํ ์ ๋น
- SET/DELTA ๊ฐ๊ฐ์ ๋ชฉ์ , ์ฌ์ฉ ์๋๋ฆฌ์ค, ์์ฒญ/์๋ต ์์๋ฅผ ๋ถ๋ฆฌํ์ฌ ๋ฌธ์ํ
- DELTA์ Idempotency-Key ๊ท์ฝ(์์ฑ ๋ฐฉ๋ฒ, ์ฌ์ฌ์ฉ ๋ฒ์, TTL, ์ค๋ณต ์ฒ๋ฆฌ)์ ๋ฌธ์ํ
- โcart ๋น์ โ cart ์ํฐํฐ ์ญ์ โ cartId ๋๋ฝ ๊ฐ๋ฅโ ์ผ์ด์ค๋ฅผ ์์/์ฃผ์์ฌํญ์ผ๋ก ๋ช ํํ ๊ธฐ์ฌ
โ ์๋ฃ ์กฐ๊ฑด(AC)
- SET API๋ก ์ต์ข ์๋ ์ค์ ์ด ๊ฐ๋ฅํ๋ฉฐ ๋์ผ ์์ฒญ ์ฌ์๋ ์ ๊ฒฐ๊ณผ๊ฐ ๋ณํ์ง ์๋๋ค(๋ฉฑ๋ฑ).
- DELTA API๋ก ์ฆ๊ฐ์ด ๊ฐ๋ฅํ๋ฉฐ ํ๋ก ํธ๋ ๋์ ์๋ ๊ณ์ฐ ์์ด
delta๋ง ์ ์กํ๋ค. - DELTA ์์ฒญ์ ๋์ผ
Idempotency-Key๋ก ์ค๋ณต ์์ฒญ์ด ๋ฐ์ํด๋ ์๋์ด ์ค๋ณต ๋ฐ์๋์ง ์๊ณ ๋์ผ ์๋ต์ด ๋ฐํ๋๋ค. delta๊ฐ์๋ก 0 ์ดํ๊ฐ ๋๋ฉด ํด๋น menu๊ฐ ์ญ์ ๋๋ฉฐ, cart๊ฐ ๋น๋ฉด cart ์ํฐํฐ๊ฐ ์ญ์ ๋๋ค(๊ธฐ์กด ์ ์ฑ ์ค์).- ๋ฌธ์/์์๊ฐ ์ค์ ๋์๊ณผ ์ผ์นํ์ฌ ํ๋ก ํธ ๊ฐ๋ฐ์๊ฐ ํผ์ ์์ด ๊ตฌํ ๊ฐ๋ฅํ๋ค.
๐ ์ถ๊ฐ๋ก ํ์ํ ๋ฐ์ดํฐ(์ถ์ธก ์์ด ์คํ ํ์ ์ํด ์์ฒญ)
์๋ ์ ๋ณด๊ฐ ์์ด์ผ API Path/Method ๋ฐ ๋ฉฑ๋ฑ์ฑ ์ ์ฅ ์ ๋ต์ ์ ํํ ํ์ ํ ์ ์์ต๋๋ค.
- ํ์ฌ ์ฌ์ฉ ์ค์ธ ์ฅ๋ฐ๊ตฌ๋ ๊ด๋ จ API์ HTTP Method / Path ๋ชฉ๋ก(๊ธฐ์กด โmenu ์ถ๊ฐ/์์ โ ์๋ํฌ์ธํธ ํฌํจ)
- ์ฌ์ฉ์ ์๋ณ ๋ฐฉ์(์ธ์ฆ: JWT ๋ฑ) ๋ฐ โcart ์์ ์โ ๊ฒฐ์ ๋ฐฉ์
- DB ๋ชจ๋ธ ์ ๋ณด
- cartItem ์ ๋ํฌ ์ ์ฝ(์: cartId+menuId unique ์ฌ๋ถ)
- cart/cartItem์ version ์ปฌ๋ผ ๋๋ ๊ณตํต audit ์ปฌ๋ผ ์กด์ฌ ์ฌ๋ถ
- Idempotency-Key๋ฅผ ์ด๋ฏธ ์ฌ์ฉํ๋ ๊ณตํต ๊ท์ฝ/๋ฏธ๋ค์จ์ด ์กด์ฌ ์ฌ๋ถ(์๋ค๋ฉด ํค๋๋ช /TTL/์ ์ฅ์)
quantity=0์ญ์ ์ ์ฑ ์ SET์์ ๊ทธ๋๋ก ์ ์งํ ์ง, DELETE๋ก ๋ถ๋ฆฌํ ์ง์ ํ ์ปจ๋ฒค์
๐โโ๏ธ ๋ด๋น์
- ๋ฐฑ์๋: ์ด๋ฆ
- ํ๋ก ํธ์๋: ์ด๋ฆ
- ๋์์ธ: ์ด๋ฆ
Metadata
Metadata
Assignees
Labels
enhancement๊ธฐ๋ฅ ๊ฐ์ /ํฅ์ (Enhancement)๊ธฐ๋ฅ ๊ฐ์ /ํฅ์ (Enhancement)์์
์ ์์
์์ ์ ์ค๋น ์ํ์์
์์ ์ ์ค๋น ์ํ