Chuyển tới nội dung chính

Common Patterns

Hướng dẫn các pattern thường dùng khi tích hợp với External API.

Pagination

Tất cả list endpoints hỗ trợ pagination qua query params:

GET /api/v1/external/listings?page=1&limit=20

Response:

{
"items": [
{ "id": "uuid", "name": "Villa Đà Lạt" }
],
"total": 100,
"page": 1,
"limit": 20,
"total_pages": 5
}

Best Practice: Sử dụng cursor-based pagination nếu available để tránh skip items khi có changes trong khi paginate.

Filtering

Một số endpoints hỗ trợ filtering:

Filter theo Teams

Listings:

# Lấy từ tất cả teams trong token
GET /api/v1/external/listings

# Filter theo teams cụ thể (JSON array string)
GET /api/v1/external/listings?team_ids=[1,2,3]

Bookings:

# Lấy từ tất cả teams
GET /api/v1/external/bookings

# Filter theo teams và customer
GET /api/v1/external/bookings?team_ids=[1,2]&user_id=200

Lưu ý:

  • Format team_ids: JSON array string "[1,2,3]"
  • Chỉ các teams hợp lệ (thuộc token) mới được sử dụng
  • Nếu không có team_ids, API trả về từ tất cả teams trong token

Filter khác

# Lọc theo status
GET /api/v1/external/listings?state=ACTIVE

# Lọc bookings theo state
GET /api/v1/external/bookings?state=CONFIRMED

# Lọc theo location
GET /api/v1/external/listings?country_code=VN&province_code=SG

Sorting

GET /api/v1/external/listings?sort_by=created_at&sort_order=desc

Error Handling

Error Response Format

{
"code": "LISTING_NOT_FOUND",
"message": "Listing not found",
"details": {}
}

Common Error Codes

CodeHTTP StatusDescription
VALIDATION_ERROR400Request body không hợp lệ
EXTERNAL_INVALID_REQUEST400Invalid request format (e.g., invalid team_ids JSON)
EXTERNAL_INVALID_STATE400Invalid state value
EXTERNAL_INVALID_DATE_FORMAT400Invalid date format
LISTING_NOT_FOUND404Listing không tồn tại
BOOKING_NOT_FOUND404Booking không tồn tại
EXTERNAL_LISTING_NOT_ACCESSIBLE404Listing không tồn tại hoặc không thuộc teams của token
EXTERNAL_BOOKING_NOT_ACCESSIBLE404Booking không tồn tại hoặc không thuộc teams của token
EXTERNAL_CUSTOMER_NOT_ACCESSIBLE403Customer không thuộc teams của token
EXTERNAL_BOOKING_ID_REQUIRED400external_booking_id required when external_system provided
RATE_LIMIT_EXCEEDED429Quá rate limit

Retry Strategy

import time

def retry_with_backoff(func, max_retries=3):
for i in range(max_retries):
try:
return func()
except Exception as e:
if i == max_retries - 1:
raise
wait_time = 2 ** i # 1, 2, 4 seconds
time.sleep(wait_time)

Rate Limiting

Xem headers để theo dõi rate limit:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1700000000

Best Practice:

  • Implement exponential backoff khi nhận 429
  • Cache data nếu có thể để giảm số requests

Webhooks

Sử dụng webhooks để nhận notifications thay vì polling:

# Example webhook handler
@app.route('/webhook', methods=['POST'])
def handle_webhook():
payload = request.json
event_type = payload.get('event_type')

if event_type == 'booking.created':
booking_id = payload.get('data', {}).get('id')
# Process booking

Xem thêm: Webhooks