์ฌ์ฉ์๊ฐ ๊ฑฐ๋๊ฐ ๊ฐ๋ฅํ Market API๋ฅผ ์์ฑํฉ๋๋ค. ์๊ตฌ์ฌํญ์ ๋ง์ถฐ ์งํํฉ๋๋ค
Test ์ฝ๋ ์์ฑ์ ํตํด ๊ฐ๋ ์ฑ๊ณผ ์ฝ๋ ํ์ง์ ํฅ์์ํต๋๋ค.
- DB ์ฑ๋ฅ ๊ฐ์
- ๋์์ฑ ํ ์คํธ ๊ฒฐ๊ณผ
- Architecture Layers
- Exception ํธ๋ค๋ง
- ์๊ตฌ์ฌํญ
- API ๋ช ์ธ
์ ํํ ์ฑ๋ฅ ๋น๊ต๋ฅผ ์ํด, ๋์ผ ๋ฐ์ดํฐ์ ๊ณผ ๋์ผ ์ฟผ๋ฆฌ ์กฐ๊ฑด์์ ์ธ๋ฑ์ค ์์ฑ/์ญ์ ์ ํ๋ฅผ ๋ฐ๋ณต ์ธก์ ํ์ต๋๋ค.
- ๋๋ฏธ ๋ฐ์ดํฐ ์์ฑ SQL:
perf/mysql/01_generate_dummy_data.sqlproduct100,000๊ฑด ์ด์,orders100,000๊ฑด ์ด์ ๋ฐ์ดํฐ ์์ฑ
- ์ธ๋ฑ์ค ๊ด๋ฆฌ SQL:
perf/mysql/02_index_manage.sql- ์คํ ๋์ ์ธ๋ฑ์ค ์์ฑ/์ญ์ ์คํฌ๋ฆฝํธ ์ ๊ณต
- ๋ฒค์น๋งํฌ ์ฟผ๋ฆฌ SQL:
perf/mysql/03_benchmark_queries.sqlEXPLAIN ANALYZE๊ธฐ๋ฐ ์กฐํ ์ฑ๋ฅ ๋น๊ต ์ฟผ๋ฆฌ ์ ๊ณต
- ์ฑ๋ฅ ์ธก์ ํ
์คํธ ์ฝ๋:
src/test/java/sample/market/performance/IndexPerformanceReportTest.java- ์ธ๋ฑ์ค ์ /ํ ์๊ฐ์ ์ธก์ ํ๊ณ ์์ฝํ ํํ๋ก ์ถ๋ ฅ
- ์๋ ์คํ ์ ์ฉ:
-DrunPerfTest=true์ต์ ํ์
์คํ ์์:
- docker compose ๋ก MySQL ์ปจํ ์ด๋ ์คํ ํ ๋๋ฏธ ๋ฐ์ดํฐ ์ ์ฌ
- ์ธ๋ฑ์ค ์๋ ์ํ/์๋ ์ํ๋ฅผ ๊ธฐ์ค์ผ๋ก
EXPLAIN ANALYZE๋น๊ต - ์ฑ๋ฅ ํ ์คํธ ์ฝ๋ ์คํ์ผ๋ก ์์น ์์ฝ
- ๊ฒฐ๊ณผ๋ฅผ ํ์ ์์ธ ๋ถ์์ผ๋ก ๋ฌธ์ํ
ํ ์คํธ ์คํ ์์:
./gradlew test --tests "sample.market.performance.IndexPerformanceReportTest" -DrunPerfTest=true| ๊ธฐ๋ฅ | ์ธ๋ฑ์ค ์ ์ฟผ๋ฆฌ ์๊ฐ | ์ธ๋ฑ์ค ํ ์ฟผ๋ฆฌ ์๊ฐ | ๊ฐ์ ์จ | ๋น๊ณ |
|---|---|---|---|---|
์ฃผ๋ฌธ ์กฐํ (orders), ์ธ๋ฑ์ค ์์ -> ๋จ์ผ ์ธ๋ฑ์ค |
47.2ms | 1.13ms | ์ฝ 97.6% ๊ฐ์ | ๋จ์ผ ์ธ๋ฑ์ค (buyer_id), product_id๋ ํ์ ํํฐ |
์ฃผ๋ฌธ ์กฐํ (orders), ์ธ๋ฑ์ค ์์ -> ๋ณตํฉ ์ธ๋ฑ์ค |
47.2ms | 0.529ms | ์ฝ 98.9% ๊ฐ์ | ๋ณตํฉ ์ธ๋ฑ์ค (buyer_id, product_id), ์กฐ๊ฑด ๋งค์นญ ์ต์ |
์ฃผ๋ฌธ ์กฐํ (orders), ๋จ์ผ ์ธ๋ฑ์ค -> ๋ณตํฉ ์ธ๋ฑ์ค |
1.13ms | 0.529ms | ์ฝ 53.2% ๊ฐ์ | ๋จ์ผ ์ธ๋ฑ์ค ๋๋น ์ถ๊ฐ ๊ฐ์ |
์ํ ์กฐํ (product.status) ์ธ๋ฑ์ค ์ ์ฉ |
20.1ms | 20.3ms | ์ฝ 1.0% ์ฑ๋ฅ ์ ํ | ๋จ์ผ ์ธ๋ฑ์ค (status, ์นด๋๋๋ฆฌํฐ๊ฐ ๋ฎ์, ์ ์๋ฏธ ๊ฐ์ ์์) |
| ์ํ ์กฐํ + OFFSET ํ์ด์ง | - | 10.2ms | - | OFFSET 20000 |
| ์ํ ์กฐํ + ์ปค์ ํ์ด์ง | - | 0.389ms | - | id < 20000 offset ๋๋น ์ฝ 96.2% ๊ฐ์ |
์กฐํ ํจํด:
WHERE buyer_id = ? AND product_id = ? ORDER BY id DESC LIMIT 100
EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE buyer_id = 123
AND product_id = 123
ORDER BY id DESC
LIMIT 100;actual time=47.2..47.2
Index scan on orders using PRIMARY (reverse) ... rows=100000
buyer_id,product_id๋ฅผ ๋ฐ๋ก ํ์ง ๋ชปํด full table scan ํ ํํฐ๋ง์ด ๋ฐ์ํ์ต๋๋ค.
EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE buyer_id = 123
AND product_id = 123
ORDER BY id DESC
LIMIT 100;actual time=1.05..1.13
Index lookup on orders using buyer_id_idx (buyer_id=123)
buyer_id์กฐ๊ฑด์ผ๋ก ํ๋ณด๊ตฐ์ ๋น ๋ฅด๊ฒ ์ค์ฌ ์ฑ๋ฅ์ด ํฌ๊ฒ ๊ฐ์ ๋์์ต๋๋ค.- ๋ค๋ง
product_id๋ ์ถ๊ฐ ๋น์ฉ์ด ๋จ์ต๋๋ค.
EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE buyer_id = 123
AND product_id = 123
ORDER BY id DESC
LIMIT 100;actual time=0.444..0.529
Index lookup on orders using buyer_product_idx (buyer_id=123, product_id=123)
- ์กฐํ ์กฐ๊ฑด์ด ๋ณตํฉ ์ธ๋ฑ์ค ์ ๋ ์ปฌ๋ผ ์์์ ์ผ์นํ์ฌ ๊ฐ์ฅ ํจ์จ์ ์ธ ๊ฒฝ๋ก๋ฅผ ํ์ต๋๋ค.
EXPLAIN ANALYZE
SELECT p.*
FROM product p
WHERE p.status = 'END_OF_SALE'
ORDER BY p.id DESC
LIMIT 20 OFFSET 20000;์ธ๋ฑ์ค ์ : actual time=20.1..20.1
์ธ๋ฑ์ค ํ: actual time=20.3..20.3
status = 'END_OF_SALE'์กฐ๊ฑด์ด ๋๋ ๋งค์นญ๋๋ ๋ถํฌ์์๋ ์ธ๋ฑ์ค ์ ํ๋๊ฐ ๋ฎ์ต๋๋ค.- ์ด๋ฒ ์ค์ธก์์๋ ์ธ๋ฑ์ค ์ ์ฉ ์ /ํ ์ฐจ์ด๊ฐ ๊ฑฐ์ ์์๊ณ (์ฝ 1% ์ ํ), ์ฑ๋ฅ ๊ฐ์ ํจ๊ณผ๊ฐ ํ์ธ๋์ง ์์์ต๋๋ค.
- ์ด ๊ตฌ๊ฐ์ ๋ณ๋ชฉ์ ์ํ ์ธ๋ฑ์ค๋ณด๋ค
OFFSET์ค์บ ๋น์ฉ ์ํฅ์ด ๋ ํฝ๋๋ค.
EXPLAIN ANALYZE
SELECT p.*
FROM product p
ORDER BY p.id DESC
LIMIT 20 OFFSET 20000;actual time=10.2..10.2 rows=20 loops=1
- ํฐ OFFSET์ ๊ฑด๋๋ฐ๊ธฐ ์ํด ๋ถํ์ํ ํ์ ๋ง์ด ์ฝ์ด์ผ ํ๋ฏ๋ก ๋น์ฉ์ด ํฝ๋๋ค.
EXPLAIN ANALYZE
SELECT p.*
FROM product p
WHERE p.id < 20000
ORDER BY p.id DESC
LIMIT 20;actual time=0.379..0.389 rows=20 loops=1
Index range scan on p using PRIMARY over (id < 20000)
- PK ๋ฒ์๋ฅผ ์ง์ ์ขํ ์ฝ๊ธฐ ๋๋ฌธ์ deep offset ๋น์ฉ์ ํผํฉ๋๋ค.
- ๋์ผ ์กฐ๊ฑด ๊ธฐ์ค OFFSET(10.2ms) ๋๋น ์ฝ 96.2% ๊ฐ์ ๋์์ต๋๋ค.
- ์ฃผ๋ฌธ ์กฐํ๋
orders(buyer_id, product_id)๋ณตํฉ ์ธ๋ฑ์ค๊ฐ ๊ฐ์ฅ ํจ๊ณผ์ ์ ๋๋ค. - ๋จ์ผ ์ธ๋ฑ์ค(
buyer_id)๋ ์๋ฏธ ์๋ ๊ฐ์ ์ ์์ง๋ง, ๋ณตํฉ ์ธ๋ฑ์ค๊ฐ ์ถ๊ฐ ์ด์ ์ ์ ๊ณตํฉ๋๋ค. - ํ์ด์ง์ deep offset ๊ตฌ๊ฐ์์ ์ปค์ ๊ธฐ๋ฐ์ด ํจ์ฌ ์ ๋ฆฌํฉ๋๋ค.
- ์ธ๋ฑ์ค ์ ์ฉ ๊ฒฐ๊ณผ, ์ฃผ๋ฌธ ์กฐํ ํต์ฌ ๊ตฌ๊ฐ์์ ์ต๋ ์ฝ 98.9% ์ฑ๋ฅ ๊ฐ์ ์ ํ์ธํ์ต๋๋ค.
- ํนํ
orders(buyer_id, product_id)๋ณตํฉ ์ธ๋ฑ์ค๋ ๋จ์ผ ์ธ๋ฑ์ค ๋๋น๋ ์ถ๊ฐ ๊ฐ์ ํจ๊ณผ๊ฐ ์์์ต๋๋ค. - ๋ฐ๋ฉด
product.status๋ ์ด๋ฒ ์ค์ธก์์ ์ธ๋ฑ์ค ์ /ํ๊ฐ ๊ฑฐ์ ๋์ผํด, ์ธ๋ฑ์ค ํจ๊ณผ๊ฐ ํฌ์ง ์์์ต๋๋ค.
- ํนํ
- ํ์ด์ง์ deep offset ๊ตฌ๊ฐ์์ ์ปค์ ๊ธฐ๋ฐ(
id < cursor)์ด ์ผ๋ฐ OFFSET ๋ฐฉ์๋ณด๋ค ํจ์ฌ ์์ ์ ์ธ ์ฑ๋ฅ์ ๋ณด์์ต๋๋ค.
- ์กฐํ(Read)๋ ๋ฆฌํ๋ฆฌ์นด DB(์ฌ๋ ์ด๋ธ)๋ก ๋ถ๋ฆฌํ๊ณ , ์ฐ๊ธฐ(Write)๋ ๋ง์คํฐ DB์์ ์ฒ๋ฆฌํ๋ ๊ตฌ์กฐ๊ฐ ์ ํจํฉ๋๋ค.
- ์ด ๊ตฌ์กฐ๋ ์ฝ๊ธฐ ๋ถํ ๋ถ์ฐ, ํธ๋ํฝ ํผํฌ ๋์, ์ํ ํ์ฅ์ฑ ํ๋ณด์ ์ ๋ฆฌํฉ๋๋ค.
StockFacadeTest์์ ๋์ผํ ์ฌ๊ณ (quantity=300)์ ๋ํด 300๊ฐ ์์ฒญ์ ๋์์ ๋ฐ์์์ผ,
๋ฝ ์ ๋ต๋ณ ์ฌ๊ณ ์ฐจ๊ฐ ๊ฒฐ๊ณผ์ ์ฒ๋ฆฌ ์๊ฐ์ ๋น๊ตํ์ต๋๋ค.
- ํ ์คํธ ์ฝ๋: StockFacadeTest.java
- ์คํ ๋ฐฉ์:
ExecutorService(100 threads)+CountDownLatch(300) - ๊ฒ์ฆ ์กฐ๊ฑด: ๋ชจ๋ ์์ฒญ ์๋ฃ ํ ์ฌ๊ณ ๊ฐ
0์ธ์ง ๊ฒ์ฆ
| ๊ตฌ๋ถ | ์ฒ๋ฆฌ ์๊ฐ |
|---|---|
| ๋น๊ด์ ๋ฝ (Pessimistic Lock) | 1.51์ด |
| ๋๊ด์ ๋ฝ (Optimistic Lock) | 16.61์ด |
- ๋์ผ ์กฐ๊ฑด์์ ๋น๊ด์ ๋ฝ์ด ๋๊ด์ ๋ฝ ๋๋น ์ฝ 11๋ฐฐ ๋น ๋ฅด๊ฒ ์ธก์ ๋์์ต๋๋ค.
- ํธ์ถ ๊ฒฝ๋ก:
StockFacade.decreaseWithPessimistic(...)StockServiceImpl.decreaseWithPessimistic(...)StockRepository.findByIdWithPessimisticLock(...)
- ๊ตฌํ ํฌ์ธํธ:
StockRepository์์@Lock(LockModeType.PESSIMISTIC_WRITE)์ฌ์ฉ- DB ๋ ๋ฒจ์์ ์ฐ๊ธฐ ๋ฝ์ ๋จผ์ ์ ์ ํ์ฌ ์ถฉ๋์ ์ง๋ ฌํ
- ํธ์ถ ๊ฒฝ๋ก:
StockFacade.decreaseWithOptimistic(...)StockServiceImpl.decreaseWithOptimistic(...)StockRepository.findByIdWithOptimisticLock(...)
- ๊ตฌํ ํฌ์ธํธ:
Stock์ํฐํฐ์@Versionํ๋ ๊ธฐ๋ฐ ์ถฉ๋ ๊ฐ์ง- ์ถฉ๋ ๋ฐ์ ์ ์ฌ์๋(backoff) ๋ก์ง ์ํ
StockFacade์ ์ฌ์๋ ๋ฃจํ(maxRetries=20, sleep 50ms ์ง์ ๋ฐฑ์คํ) +StockServiceImpl๋ด๋ถ ์ฌ์๋ ๋๊ธฐ(Thread.sleep(100))๋ก ์ธํด ๊ณ ๊ฒฝํฉ ์ํฉ์์ ๋์ ์ง์ฐ์ด ์ปค์ง
- ๋ณธ ์๋๋ฆฌ์ค์ฒ๋ผ ๋์ผ row์ ๋ํ ๊ณ ๊ฒฝํฉ(300๊ฑด ๋์ ๊ฐฑ์ )์์๋, ์ถฉ๋ ์ดํ ์ฌ์๋ ๋น์ฉ์ด ํฐ ๋๊ด์ ๋ฝ๋ณด๋ค ๋น๊ด์ ๋ฝ์ด ๋ ์ ๋ฆฌํ์ต๋๋ค.
- ๋ฐ๋๋ก, ์ถฉ๋ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๊ณ ์ฝ๊ธฐ ๋น์ค์ด ๋์ ํธ๋ํฝ์์๋ ๋๊ด์ ๋ฝ์ด ์ ๋ฆฌํ ์ ์์ด, ํธ๋ํฝ ํน์ฑ์ ๋ฐ๋ผ ๋ฝ ์ ๋ต์ ๋ถ๋ฆฌ ์ ์ฉํ๋ ๊ฒ์ด ์ ์ ํฉ๋๋ค.
์ฌ์ ์ค๋น:
- Redis/MySQL ์คํ ํ์ (
docker-compose.yml๊ธฐ์ค)
์คํ ์์:
./gradlew test --tests "sample.market.application.product.stock.StockFacadeTest"Layer ๊ฐ์ ์ฐธ์กฐ ๊ด๊ณ์์๋ ๋จ๋ฐฉํฅ ์์กด ์ ์ง๋ฅผ ํตํด ํ์ฅ์ ์ ์ฐํ ์ํคํ ์ฒ๋ก ์ค๊ณํฉ๋๋ค.
๊ฐ๊ฒฐํ๊ณ ์ฝ๊ธฐ ์ฌ์ด ์ฝ๋๋ก ์์ฑํฉ๋๋ค.
์ฑ ์๊ณผ ์ญํ ์ ์ ๊ตฌ๋ถํฉ๋๋ค.
Layer ๊ฐ ์ฐธ์กฐ ๊ด๊ณ
- application๊ณผ infrastructure ๋ domain Layer ๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๊ณ ์๋ฐฉํฅ ์ฐธ์กฐ๋ ํ์ฉํ์ง ์์ต๋๋ค.
Application Layer
- transaction์ผ๋ก ๋ฌถ์ฌ์ผ ํ๋ ๋๋ฉ์ธ ๋ก์ง๊ณผ ๊ทธ๋ ์ง ์๋ ๋ก์ง์ ๊ตฌ๋ถํฉ๋๋ค.
- ์๋ฅผ ๋ค์ด ํ์๊ฐ์ ํ ํ์๊ฐ์ ์ฑ๊ณต ์ด๋ฉ์ผ ๋ฐ์ก์ ๊ฒฝ์ฐ ์ด๋ฉ์ผ ๋ฐ์ก์ธ ์ธ๋ถ ์๋น์ค call์ ํ์๊ฐ์ ๋๋ฉ์ธ ๋ก์ง์ ํฌํจ๋์ง ์์ผ๋ฏ๋ก transaction์์ ๋ถ๋ฆฌ์ํค๋ฉฐ ํ์๊ฐ์ ๋๋ฉ์ธ ๋ก์ง์ ์ธ๋ถ ์๋น์ค call ์ฑ๊ณต / ์คํจ ์ฌ๋ถ์ ๋ํด ํฌ๊ฒ ๋ฏผ๊ฐํ์ง ์๊ฒ ์ฒ๋ฆฌ๋๋ค.
Domain Layer
- domain Layer๋ low level์ ๊ธฐ์ ์ ๊ด๊ณ์์ด ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌํฉ๋๋ค.
- domain layer ์์๋ ๋๋ฉ์ธ ๋ก์ง์ ํ๋ฆ์ ํํํ๊ณ ๊ตฌํํ๋ Service ์ ServiceImpl ์ด ์์ง๋ง ๊ทธ ์ธ์ ์์ธํ ๊ตฌํ์ Reader, Store, Executor ๊ฐ์ interface ๋ฅผ ์ ์ธํ์ฌ ์ฌ์ฉํ๊ณ ์ด์ ๋ํ ์ค์ ๊ตฌํ์ฒด๋ Infrastructure layer ์ ๋๊ณ ํ์ฉํฉ๋๋ค.
Infrastructure Layer
- domain layer ์ ์ ์ธ๋๊ณ ์ฌ์ฉ๋๋ ์ถ์ํ๋ interface ๋ฅผ ์ค์ ๋ก ๊ตฌํํ์ฌ runtime ์์๋ ์ค์ ๋ก์ง์ด ๋์ํฉ๋๋ค.
- Service ๊ฐ์ ์ฐธ์กฐ ๊ด๊ณ๋ ๋ง์์ง๋ง, Infrastructure layer ์์์ ๊ตฌํ์ฒด ๊ฐ์๋ ์ฐธ์กฐ ๊ด๊ณ๋ฅผ ํ์ฉํฉ๋๋ค.
Interfaces Layer
- API ๋ฅผ ์ค๊ณํ ๋์๋ ์์ด๋ ๋๋ Request Parameter ๋ ์ ๊ฑฐํ๊ณ , ์ธ๋ถ์ ๋ฆฌํดํ ๋ Response ๋ ์ต์ํ์ ์ ์งํ๋๋ก ๋ ธ๋ ฅํฉ๋๋ค.
- http, gRPC, ๋น๋๊ธฐ ๋ฉ์์ง๊ณผ ๊ฐ์ ์๋น์ค๊ฐ ํต์ ๊ธฐ์ ์ Interfaces layer ์์๋ง ์ฌ ์ฉ๋๋๋ก ํฉ๋๋ค.
Interfaces
- xxApiController
- xxDto
Application Layer
- xxFacade
Domain Layer
- Entity
- xxService
- xxServiceImpl
- xxReader
- xxStore
- xxCommand
- xxInfo
- xxManager
- xxManagerImpl
- xxMapper
Infrastructure
- xxReaderImpl
- xxRepository
- xxStoreImpl
๊ฐ๋ ์ฑ๊ณผ ํธ์๋ฅผ ์ํด ํ์ค์์ธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ์๋ชป๋ ์ธ์ ์ ๋ ฅ์ IllegalArgumentException ์ ๋ฐํํฉ๋๋ค.
- ์๋ชป๋ ์ํ์ผ ๊ฒฝ์ฐ IllegalStateException ๋ฅผ ๋ฐํํฉ๋๋ค.
์์คํ
์์ธ ์ํฉ (์ง์ค ๋ชจ๋ํฐ๋ง ์ฒ๋ฆฌ) ์ ๋น์ฆ๋์ค ๋ก์ง ์๋ฌ ์ํฉ์ GlobalControllerAdvice ์์ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค.
- ์์คํ ์์ธ / http status : 500 AND result : FAIL
- ๋น์ฆ๋์ค ๋ก์ง ์๋ฌ / http status : 200 AND result : FAIL
- ์๋ชป๋ ์ธ์ ์ ๋ ฅ ์์ธ / http status : 400 AND result : FAIL
1๋จ๊ณ
- ์ ์ ๋ ์ ํ๋ฑ๋ก์ ํ ์ ์์ต๋๋ค.
- ๋ฑ๋ก๋ ์ ํ์๋ "์ ํ๋ช ", "๊ฐ๊ฒฉ", "์์ฝ์ํ"๊ฐ ํฌํจ๋์ด์ผํ๊ณ , ๋ชฉ๋ก์กฐํ์ ์์ธ์กฐํ์์ ์์ฝ์ํ๋ฅผ ํฌํจํด์ผํฉ๋๋ค.
- ์ ํ์ ์ํ๋ "ํ๋งค์ค", "์์ฝ์ค", "์๋ฃ" ์ธ๊ฐ์ง๊ฐ ์กด์ฌํฉ๋๋ค.
- ๊ตฌ๋งค์๊ฐ ์ ํ์ ์์ธํ์ด์ง์์ ๊ตฌ๋งคํ๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ฑฐ๋๊ฐ ์์๋ฉ๋๋ค.
- ํ๋งค์์ ๊ตฌ๋งค์๋ ์ ํ์ ์์ธ์ ๋ณด๋ฅผ ์กฐํํ๋ฉด ๋น์ฌ์๊ฐ์ ๊ฑฐ๋๋ด์ญ์ ํ์ธํ ์ ์์ต๋๋ค.
- ๋ชจ๋ ์ฌ์ฉ์๋ ๋ด๊ฐ "๊ตฌ๋งคํ ์ฉํ(๋ด๊ฐ ๊ตฌ๋งค์)"๊ณผ "์์ฝ์ค์ธ ์ฉํ(๋ด๊ฐ ๊ตฌ๋งค์/ํ๋งค์ ๋ชจ๋)"์ ๋ชฉ๋ก์ ํ์ธํ ์ ์์ต๋๋ค.
- ํ๋งค์๋ ๊ฑฐ๋์งํ์ค์ธ ๊ตฌ๋งค์์ ๋ํด 'ํ๋งค์น์ธ'์ ํ๋ ๊ฒฝ์ฐ ๊ฑฐ๋๊ฐ ์๋ฃ๋ฉ๋๋ค.
2๋จ๊ณ
- ์ ํ์ ์๋์ด ์ถ๊ฐ๋ฉ๋๋ค. ์ ํ์ ๋ณด์ "์ ํ๋ช ", "๊ฐ๊ฒฉ", "์์ฝ์ํ", "์๋"์ด ํฌํจ๋์ด์ผํฉ๋๋ค.
- ๋ค์์ ๊ตฌ๋งค์๊ฐ ํ ์ ํ์ ๋ํด ๊ตฌ๋งคํ๊ธฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. (๋จ, ํ ๋ช ์ด ๊ตฌ๋งคํ ์ ์๋ ์๋์ 1๊ฐ๋ฟ์ ๋๋ค.)
- ๊ตฌ๋งคํ์ ์ ๋จ๊ณ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ๊ตฌ๋งค์๋ ํ๋งค์๊ฐ ํ๋งค์น์ธํ ์ ํ์ ๋ํด ๊ตฌ๋งคํ์ ์ ํ ์ ์์ต๋๋ค.
- ๊ฑฐ๋๊ฐ ์์๋๋ ๊ฒฝ์ฐ ์๋์ ๋ฐ๋ผ ์ ํ์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค.
- ์ถ๊ฐ ํ๋งค๊ฐ ๊ฐ๋ฅํ ์๋์ด ๋จ์์๋ ๊ฒฝ์ฐ - ํ๋งค์ค
- ์ถ๊ฐ ํ๋งค๊ฐ ๋ถ๊ฐ๋ฅํ๊ณ ํ์ฌ ๊ตฌ๋งคํ์ ์ ๋๊ธฐํ๊ณ ์๋ ๊ฒฝ์ฐ - ์์ฝ์ค
- ๋ชจ๋ ์๋์ ๋ํด ๋ชจ๋ ๊ตฌ๋งค์๊ฐ ๋ชจ๋ ๊ตฌ๋งคํ์ ํ ๊ฒฝ์ฐ - ์๋ฃ
- "๊ตฌ๋งคํ ์ฉํ"๊ณผ "์์ฝ์ค์ธ ์ฉํ" ๋ชฉ๋ก์ ์ ๋ณด์์ ๊ตฌ๋งคํ๊ธฐ ๋น์์ ๊ฐ๊ฒฉ ์ ๋ณด๊ฐ ๋ํ๋์ผํฉ๋๋ค.
- ์) ๊ตฌ๋งค์ A๊ฐ ๊ตฌ๋งคํ๊ธฐ ์์ฒญํ ๋น์์ ์ ํ B์ ๊ฐ๊ฒฉ์ด 3000์์ด์๊ณ ์ดํ์ 4000์์ผ๋ก ๋ฐ๋์๋ค ํ๋๋ผ๋ ๋ชฉ๋ก์์๋ 3000์์ผ๋ก ๋ํ๋์ผํฉ๋๋ค.
- ์ฌ๊ธฐ์์ ์์ฝ์ค์ ์ํ์ ์ํ ์์ฝ์ค์ด ์๋ ๊ฑฐ๋ ์ํ์ ์์ฝ์ค์ ์๋ฏธํ๋ค.
๊ตฌ๋งค์ทจ์๋ ๊ณ ๋ คํ์ง ์์ต๋๋ค. ๊ฒ์ฆ์ด ํ์ํ ๋ถ๋ถ์ ๋ํด ํ ์คํธ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์ธ์. ์์ฑํ API์ ๋ํ ๋ช ์ธ๋ฅผ ์์ฑํด์ฃผ์ธ์.
{
"name" : "sample",
"price" : 123
}buyerId: ๊ตฌ๋งค์ Id
buyerId: ๊ตฌ๋งค์ Id
sellerId: ํ๋งค์ Id
{
"buyerId" : 123,
"productId" : 123
}{
"sellerId" : 123,
"productId" : 123
}{
"sellerId" : 123,
"productId" : 123,
"orderId" : 5000
}buyerId: ๊ตฌ๋งค์ Id
{
"email" : "sample@gmail.com",
"username" : "username",
"password" : "password"
}