صفحه‌بندی (Pagination) در GraphQL با FastAPI

  • مدرس : علی بیگدلی
  • تاریخ انتشار: 1404/06/24
  • تعداد بازدید: 1

صفحه‌بندی (Pagination) در GraphQL با FastAPI

در پروژه‌های بزرگ، ممکن است تعداد داده‌ها بسیار زیاد باشد و بارگذاری تمام آن‌ها در یک Query باعث کندی و مصرف بیش از حد منابع شود. به همین دلیل، صفحه‌بندی (Pagination) به شما اجازه می‌دهد که داده‌ها را به بخش‌های کوچک‌تر تقسیم کرده و فقط قسمت مورد نیاز را ارسال کنید.

روش‌های رایج صفحه‌بندی

  • Offset/Limit: ساده‌ترین روش صفحه‌بندی که در آن شما مشخص می‌کنید از کدام ردیف شروع شود (offset) و حداکثر چند ردیف دریافت شود (limit). این روش به سرعت قابل پیاده‌سازی است و برای اکثر موارد کافی است.
  • Relay Cursor-based Pagination: در این روش به جای شماره صفحه یا offset، از یک cursor استفاده می‌شود که نشان‌دهنده آخرین آیتم دریافت شده است. این روش مناسب داده‌های پویا و تغییرات مداوم است و باعث می‌شود کارایی و ثبات داده‌ها بهتر حفظ شود.

پیاده‌سازی Offset/Limit در FastAPI + GraphQL

فرض کنید می‌خواهیم تسک‌های یک کاربر را به صورت صفحه‌بندی شده دریافت کنیم. ابتدا Resolver را با پارامترهای skip و limit تعریف می‌کنیم:

# graphql/tasks.py
import strawberry
from graphql.context import get_current_user
from models.tasks import Task as TaskModel
from graphql.types import TaskType

@strawberry.type
class TaskQuery:

    @strawberry.field
    def tasks_paginated(self, info, skip: int = 0, limit: int = 10) -> list[TaskType]:
        db = info.context["db"]
        auth_header = info.context["request"].headers.get("authorization")
        current_user = get_current_user(auth_header, db)

        tasks = db.query(TaskModel)\
                  .filter(TaskModel.user_id == current_user.id)\
                  .offset(skip)\
                  .limit(limit)\
                  .all()

        return [
            TaskType(
                id=task.id,
                title=task.title,
                completed=task.completed,
                user_id=task.user_id,
                created_at=str(task.created_at),
                updated_at=str(task.updated_at)
            ) for task in tasks
        ]

نحوه استفاده از Query صفحه‌بندی شده

برای دریافت داده‌های صفحه اول با حداکثر 10 آیتم:

{
  tasksPaginated(skip: 0, limit: 10) {
    id
    title
    completed
  }
}

برای دریافت صفحه دوم، کافی است مقدار skip را برابر تعداد آیتم‌های صفحه اول قرار دهید:

{
  tasksPaginated(skip: 10, limit: 10) {
    id
    title
    completed
  }
}

مزایای Offset/Limit

  • ساده و سریع برای پیاده‌سازی
  • مناسب اکثر پروژه‌های کوچک تا متوسط

محدودیت‌ها

  • اگر داده‌ها به طور مداوم تغییر کنند (مثلاً حذف یا اضافه شوند)، صفحات بعدی ممکن است داده‌ها را از دست بدهند یا تکراری شوند.
  • برای مجموعه‌های بزرگ با میلیون‌ها رکورد، offset بالا باعث کاهش کارایی می‌شود.

نکات پایانی

در مراحل بعد می‌توانیم Cursor-based Pagination (مانند استاندارد Relay) را اضافه کنیم تا صفحه‌بندی در شرایط داده‌های پویا و بزرگ بهینه‌تر شود. برای شروع و اکثر موارد، روش Offset/Limit ساده، قابل فهم و عملی است و می‌توان آن را به راحتی با Resolverهای موجود ترکیب کرد.

ثبت دیدگاه


نکته: آدرس ایمیل شما منتشر نخواهد شد

دیدگاه کاربران (0)


هیچ دیدگاهی ثبت نشده است. می‌توانید اولین نفر باشید.