/available :Checks for all the available parking route for that time including if someone has early checkout
/Reserve:Proceed to book the slot includes one more route
/payment: With intent of successs and failure
/show-reservation:For user to check his current reservation And his previous reservation
/check-in: When user arrives and checks in
/expiry:when the time slot get expires
/check-out:If user does early checkout before expiry
Flow:
User → API Gateway → Slot Service → Cache (Redis) → DB (if cache miss)
Details:
Flow:
User → API Gateway → Reservation Service → DB (authoritative) → Lock
Details:
Reservation Flow:
PENDING_PAYMENT.slotsreservationspaymentsImportant principle:
All final booking decisions happen via DB transactions, NOT cache
Reservation Service → Payment Service → Stripe → Webhook → Reservation Service
PENDING_PAYMENT)reservation.status = CONFIRMEDPENDINGreservation.status = EXPIREDSELECT FOR UPDATE)UNIQUE(slot_id, time_range)
Only DB commit decides booking success — cache is advisory
Flow:
Checkout Service → DB update → Event → Cache invalidation
| Use CaseStrategy | |
| Slot availability | Redis (TTL 2 min) |
| Fully booked optimization | Redis flag (TTL 10–15 min) |
| Reservation | ❌ No cache (DB only) |
Cache is never trusted for final booking
location + timeAVAILABLE
↓
LOCKED (temporary)
↓
PENDING_PAYMENT
↓ ↓
CONFIRMED EXPIRED
Request: Reserve Slot
Client → API Gateway → Reservation Service
Steps:
SELECT ... FOR UPDATE)status = PENDING_PAYMENT
expires_at = now + 2 minutes
reservations
id (PK)
slot_id (FK)
user_id
start_time
end_time
status (PENDING_PAYMENT, CONFIRMED, EXPIRED)
expires_at
created_at
Constraint (Critical):
UNIQUE(slot_id, start_time, end_time)
or more realistically:
SELECT * FROM slots WHERE id = ? FOR UPDATE
Why both?
WHERE status = PENDING_PAYMENT AND expires_at < now()
EXPIREDAlternative:
Assume:
DB Writes:
Locks:
| ApproachProsCons | ||
| DB-only locking | Strong consistency | Higher latency, contention |
| Redis-only locking | Fast | Risk of inconsistency |
| Hybrid | Balanced | Slight complexity |
Reservation Service → Payment Service → Stripe
payment_id → reservation_id
Stripe → Webhook → Payment Service → Reservation Service
Webhook Handling:
reservation.status = CONFIRMED
PENDING_PAYMENTReason:
Webhook → Queue → Worker
Assume:
Solution:
| Design ChoiceTradeoff | |
| Webhook-driven | Eventually consistent |
| Synchronous verification | Higher latency |
| Queue-based processing | Adds complexity but improves resilience |
Client → API Gateway → Slot Service → Redis → DB (fallback)
slots:{location_id}:{time_bucket}
Checkout → DB update → Event → Cache invalidation
ZSET: slots by price or distance
slot_id → metadata
(location_id, start_time, end_time)
Assume:
Redis:
DB fallback:
| ApproachProsCons | ||
| Aggressive caching | Fast | Stale data risk |
| No caching | Accurate | High DB load |
| Short TTL + invalidation | Balanced | Slight complexity |