صفحهبندی و جستجو (Pagination & Filtering)¶
مقدمه¶
تمامی اندپوینتهای لیستگیری از سیستم صفحهبندی و فیلترینگ پیشرفته پشتیبانی میکنند. این امکان به کلاینتها اجازه میدهد دادهها را به صورت بهینه دریافت و مدیریت کنند.
ساختار پاسخ استاندارد¶
فرمت¶
{
"heads": {
"uid": "شناسه",
"created_at": "تاریخ ایجاد",
"updated_at": "تاریخ بهروزرسانی"
},
"items": [
{
"uid": "item_1",
"field1": "value1",
"field2": "value2"
},
{
"uid": "item_2",
"field1": "value1",
"field2": "value2"
}
],
"total": 100,
"offset": 0,
"limit": 10
}
توضیحات فیلدها¶
heads¶
یک آبجکت که کلیدهای (فیلدهای) موجود در هر آیتم از items را تعریف میکند. این برای اعتبارسنجی و مستندسازی داینامیک استفاده میشود.
مثال:
"heads": {
"uid": "شناسه منحصر به فرد",
"symbol": "نماد معاملاتی",
"side": "جهت سفارش",
"price": "قیمت",
"quantity": "حجم"
}
items¶
آرایهای از آیتمهای نتیجه که با پارامترهای صفحهبندی فیلتر شدهاند.
total¶
تعداد کل آیتمهای موجود بدون در نظر گرفتن صفحهبندی.
offset¶
شروع صفحهبندی (تعداد آیتمهای رد شده از ابتدا).
limit¶
حداکثر تعداد آیتمهای در هر صفحه.
پارامترهای صفحهبندی¶
offset¶
-
نوع: integer
-
پیشفرض: 0
-
حداقل: 0
-
کاربرد: مشخص میکند از کدام آیتم شروع شود
مثال:
limit¶
-
نوع: integer
-
پیشفرض: 10
-
حداقل: 1
-
حداکثر: 100
-
کاربرد: مشخص میکند چند آیتم در هر صفحه نمایش داده شود
مثال:
فیلترهای تاریخ¶
created_at_from¶
-
نوع: string (ISO 8601)
-
کاربرد: فیلتر آیتمهای ایجاد شده از این تاریخ
مثال:
created_at_to¶
-
نوع: string (ISO 8601)
-
کاربرد: فیلتر آیتمهای ایجاد شده تا این تاریخ
مثال:
ترکیب فیلترهای تاریخ¶
فیلترهای اختصاصی هر ریسورس¶
User API¶
# فیلتر بر اساس وضعیت
GET /api/user/v1/users?status=active
# فیلتر بر اساس نقش
GET /api/user/v1/users?role=trader
# جستجو در نام یا ایمیل
GET /api/user/v1/users?search=john
Wallet API¶
# فیلتر بر اساس نوع کیف پول
GET /api/accounting/v1/wallets?type=spot
# فیلتر بر اساس موجودی
GET /api/accounting/v1/wallets?min_balance=1000000
Exchange API - Orders¶
# فیلتر بر اساس کاربر
GET /api/exchange/v1/orders?user_id=user_123
# فیلتر بر اساس نماد
GET /api/exchange/v1/orders?symbol=BTC-IRR
# فیلتر بر اساس جهت
GET /api/exchange/v1/orders?side=buy
# فیلتر بر اساس وضعیت
GET /api/exchange/v1/orders?status=active
# ترکیب چند فیلتر
GET /api/exchange/v1/orders?user_id=user_123&symbol=BTC-IRR&status=active
Exchange API - Trades¶
# فیلتر بر اساس نماد
GET /api/exchange/v1/trades?symbol=BTC-IRR
# فیلتر بر اساس کاربر
GET /api/exchange/v1/trades?user_id=user_123
# فیلتر بر اساس کیف پول
GET /api/exchange/v1/trades?wallet_id=wallet_456
# فیلتر بر اساس سفارش
GET /api/exchange/v1/trades?order_id=order_789
# فیلتر بر اساس جهت
GET /api/exchange/v1/trades?order_side=buy
نمونههای کامل¶
نمونه 1: دریافت لیست سفارشات با فیلتر کامل¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?\
user_id=user_123&\
symbol=BTC-IRR&\
side=buy&\
status=active&\
created_at_from=2025-12-01T00:00:00Z&\
created_at_to=2025-12-31T23:59:59Z&\
offset=0&\
limit=10" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ موفق (200 OK):
{
"heads": {
"uid": "شناسه",
"user_id": "کاربر",
"symbol": "نماد",
"side": "جهت",
"type": "نوع",
"price": "قیمت",
"quantity": "حجم",
"status": "وضعیت",
"created_at": "تاریخ ایجاد"
},
"items": [
{
"uid": "ord_001",
"user_id": "user_123",
"symbol": "BTC-IRR",
"side": "buy",
"type": "limit",
"price": "1000000000",
"quantity": "0.5",
"status": "active",
"created_at": "2025-12-15T10:30:00Z"
},
{
"uid": "ord_002",
"user_id": "user_123",
"symbol": "BTC-IRR",
"side": "buy",
"type": "limit",
"price": "999000000",
"quantity": "0.3",
"status": "active",
"created_at": "2025-12-16T14:20:00Z"
}
],
"total": 25,
"offset": 0,
"limit": 10
}
نمونه 2: صفحه دوم با 20 آیتم¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?offset=20&limit=20" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ موفق (200 OK):
{
"heads": {
"uid": "شناسه",
"symbol": "نماد",
"side": "جهت",
"status": "وضعیت"
},
"items": [
{
"uid": "ord_021",
"symbol": "ETH-IRR",
"side": "sell",
"status": "filled"
},
{
"uid": "ord_022",
"symbol": "BTC-IRR",
"side": "buy",
"status": "active"
}
// ... 18 آیتم دیگر
],
"total": 100,
"offset": 20,
"limit": 20
}
نمونه 3: لیست خالی (بدون نتیجه)¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?status=nonexistent_status" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ موفق (200 OK):
{
"heads": {
"uid": "شناسه",
"symbol": "نماد",
"side": "جهت",
"status": "وضعیت"
},
"items": [],
"total": 0,
"offset": 0,
"limit": 10
}
نمونه 4: درخواست با offset بزرگتر از total¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?offset=1000&limit=10" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ موفق (200 OK):
{
"heads": {
"uid": "شناسه",
"symbol": "نماد"
},
"items": [],
"total": 100,
"offset": 1000,
"limit": 10
}
نمونههای ناموفق¶
نمونه 1: limit بیشتر از حداکثر¶
درخواست:
پاسخ خطا (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["query", "limit"],
"msg": "ensure this value is less than or equal to 100",
"type": "value_error.number.not_le",
"ctx": {"limit_value": 100}
}
]
}
نمونه 2: offset منفی¶
درخواست:
پاسخ خطا (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["query", "offset"],
"msg": "ensure this value is greater than or equal to 0",
"type": "value_error.number.not_ge",
"ctx": {"limit_value": 0}
}
]
}
نمونه 3: فرمت تاریخ نامعتبر¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?created_at_from=2025/12/01" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ خطا (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["query", "created_at_from"],
"msg": "invalid datetime format, expected ISO 8601",
"type": "value_error.datetime"
}
]
}
نمونه 4: پارامتر نامعتبر¶
درخواست:
curl -X GET "{BASE_URL}/api/exchange/v1/orders?invalid_param=value" \
-H "Authorization: Bearer $JWT_TOKEN"
پاسخ خطا (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["query", "invalid_param"],
"msg": "extra fields not permitted",
"type": "value_error.extra"
}
]
}
الگوریتم صفحهبندی¶
محاسبه صفحات¶
# تعداد کل صفحات
total_pages = ceil(total / limit)
# صفحه فعلی
current_page = floor(offset / limit) + 1
# صفحه بعدی
next_offset = offset + limit
next_page = current_page + 1
# صفحه قبلی
prev_offset = max(0, offset - limit)
prev_page = max(1, current_page - 1)
مثال محاسبه¶
total = 100
offset = 20
limit = 10
total_pages = ceil(100 / 10) = 10
current_page = floor(20 / 10) + 1 = 3
next_offset = 20 + 10 = 30
prev_offset = max(0, 20 - 10) = 10
چکلیست استفاده¶
قبل از هر درخواست:
-
[ ] offset و limit تنظیم شدهاند
-
[ ] فیلترهای تاریخ در صورت نیاز اضافه شدهاند
-
[ ] فیلترهای اختصاصی ریسورس استفاده شدهاند
-
[ ] پارامترها معتبر هستند
-
[ ] توکن احراز هویت ارسال شده است
خلاصه¶
-
صفحهبندی:
offsetوlimit(حداکثر 100) -
فیلتر تاریخ:
created_at_fromوcreated_at_to -
فیلتر اختصاصی: بر اساس هر ریسورس
-
پاسخ استاندارد: شامل
heads,items,total,offset,limit
بعدی: مطالعه خطاها و پاسخهای ناموفق