سلام , در این نوشته میخواهم چند روش مرسوم صفحهبندی در ایپیآی را معرفی کنم :)
در اندپوینت هایی که یک لیست بزرگ از آیتمها را بر میگردانند , ما به صفحهبندی نیاز داریم تا فشار زیادی به سرور, شبکه و... وارد نشود (آیتمها در اینجا میتواند لیستی از پستها و یا محصولات ما باشند).

این روش که دلیل معروفیتش قابلیت LIMIT و OFFSET در SQL ها است, میتواند در سرویس های کوچک استفاده شود, برای مثال با صدا زدن این اندپوینت سرور بیست آیتم بر میگرداند (آیتم 100 تا 120) :
GET/items?limit=20&offset=100
در حقیقت کاربر با offset به ما میگوید از آیتم چندم به بعد را میخواهد و با limit حداکثر تعداد آیتم های که میخواهد را مشخص میکند.
کاربر این درخواست را میفرستد و 20 آیتم اول را میگیرد :
GET /items?limit=20
سپس درخواست دوم را میفرستد و 20 آیتم بعدی را میگیرد :
GET /items?limit=20&offset=20
باز هم وقتی کاربر به صفحه سوم میرود برای گرفتن 20 آیتم بعدی این درخواست را میفرستد و از آیتم 40ام به بعد را میگیرد:
GET /items?limit=20&offset=40
این درخواست ها در سمت سرور به کوئری های دیتابیس تبدیل میشوند, برای مثال کوئری درخواست سوم:
SELECT * FROM Items ORDER BY Id LIMIT 20 OFFSET 40;
سناریو آیتم تکراری:
GET /items?offset=0&limit=15GET /items?offset=15&limit=15 این درخواست فقط پنج آیتم جدید برای کاربر ارسال میکند و ده تا از آیتمها تکراری هستند و کاربر آنها را در درخواست اول گرفته است ( در صفحه اول ده آیتم اضافه شده , به همین دلیل ده تا از آیتم های که قبلا عضو صفحه اول بودند به صفحه دوم منتقل شدند), کاربر برای حل کردن این مشکل باید این درخواست را به عنوان درخواست دومش ارسال میکرد تا آیتم تکراری نگیرد: /items?offset=25&limit=15 حتی با وجود محدودیتها، پیادهسازی و درک صفحهبندی Offset آسان است و میتوان از آن در برنامههایی استفاده کرد که لیست دادهها دارای تعداد و تغیرات کم هستند.
این روش با استفاده از یکی از فیلد های دیتابیس عملیات مرتب کردن یا Sorting را انجام میدهد.
فرض کنید آیتم های دیتابیس بر اساس تاریخ ایجاد آیتم به صورت نزولی مرتب شده است
GET /items?limit=20GET /items?limit=20&created:lte:2021-01-20T00:00:00created را بیابد و درخواست سوم را بسازد :GET /items?limit=20&created:lte:2021-01-19T00:00:00درخواست دوم وقتی به کوئری دیتابیس تبدیل میشود:
SELECT * FROM Items WHERE created <= '2021-01-20T00:00:00' ORDER BY Id LIMIT 20
این نوع صفحهبندی میتواند برای دادههای که دارای فیلد های مثل timestamp هستند استفاده شود.
این روش کامل کننده روش قبل است , با اضافه کردن یک after_id یا star_id میتوان بعضی از محدودیت های روش قبل را حذف کرد
(فرض کنید میخواهیم آیتمها نسبت به زمان ساخته شدن آنها به صورت صعودی صفحه بندی شوند)
GET /items?limit=20GET /items?limit=20&after_id=20 GET /items?limit=20&after_id=40درخواست دوم وقتی به کوئری دیتابیس تبدیل میشود :
SELECT * FROM Items WHERE Id > 20 LIMIT 20
در مثال بالا همه چیز به خوبی کار میکند , اما اگر بخواهیم دیتا را با فیلد ایمیل مرتب کنیم چه میشود؟
در این حالت کلاینت چنین درخواستی برای بکاند میفرستد: GET /items?limit=20&after_id=20&sort_by=email
بکاند برای هر درخواست نیاز دارد دو کوئری دیتابیس بزند, ابتدا باید بداند ایمیل آن آیتم که کاربر id آن را در پارامتر after_id ارسال کرده است چیست, پس با کوئری اول ایمیل آن آیتم را میگرد, سپس در کوئری دوم آیتم هارا با استفاده از ایمیل و id مرتب میکند و فقط آیتم های که ایمیل انها بعد از آن ایمیل هست را بر میگرداند (ما بر اساس هر دو ستون، ایمیل و id مرتبسازی میکنیم تا اطمینان حاصل کنیم که مرتبسازی پایداری در صورت یکسان بودن دو ایمیل داریم؛ این برای حالت های که از فیلدی با خصوصیت تکرار بالا استفاده میکنیم حیاطی است)
کوئری اول:
SELECT email AS AFTER_EMAIL FROM Items WHERE Id = 20
کوئری دوم:
SELECT * FROM Items WHERE Email >= [AFTER_EMAIL] ORDER BY Email, Id LIMIT 20
after_id ممکن است یک شناسه معتبر نباشد.این روش صفحهبندی با اینکه به کمی کار بیشتر در بکاند نیاز دارد، اما تضمین میکند که پیچیدگی اضافی به کلاینتها/کاربران API اضافه نمیشود، و حتی با جستجوهای بزرگتر هم کارآمد باقی میماند.
لینک اصلی مقاله :