دریافت دادههای تو در تو (Nested) در GraphQL با FastAPI
یکی از قابلیتهای مهم GraphQL امکان درخواست دادههای تو در تو است. به عنوان مثال، وقتی میخواهیم اطلاعات یک Task را دریافت کنیم، میتوانیم همزمان اطلاعات کاربر مرتبط با آن Task را هم دریافت کنیم، بدون نیاز به چندین درخواست جداگانه به سرور.
۱. تعریف Schemaهای تو در تو
# graphql/users.py
import strawberry
@strawberry.type
class UserType:
id: int
name: str
email: str
# graphql/tasks.py
import strawberry
from graphql.users import UserType
@strawberry.type
class TaskType:
id: int
title: str
completed: bool
user: UserType # اطلاعات کاربر مرتبط
۲. Resolver برای Task با داده کاربر
# graphql/tasks.py
from config.database import SessionLocal
from models.tasks import Task as TaskModel
from models.users import User as UserModel
@strawberry.type
class TaskQuery:
@strawberry.field
def tasks(self, info) -> list[TaskType]:
db = info.context["db"]
tasks = db.query(TaskModel).all()
result = []
for task in tasks:
user = db.query(UserModel).filter(UserModel.id == task.user_id).first()
result.append(TaskType(
id=task.id,
title=task.title,
completed=task.completed,
user=UserType(
id=user.id,
name=user.name,
email=user.email
)
))
return result
۳. مثال Query تو در تو
{
tasks {
id
title
completed
user {
id
name
email
}
}
}
توضیح
- در GraphQL میتوان مشخص کرد که چه فیلدهایی از Task و چه فیلدهایی از User دریافت شود.
- این روش باعث کاهش تعداد درخواستها و افزایش کارایی میشود، به ویژه در اپلیکیشنهای تکصفحهای (SPA) یا موبایل.
- Resolver برای Task در این مثال، علاوه بر دادههای Task، دادههای کاربر مرتبط را هم برمیگرداند و TaskType شامل یک فیلد
user
از نوع UserType است. - در پروژههای بزرگتر میتوان از روشهای بهینهسازی مثل
selectinload
یاjoinedload
در SQLAlchemy برای کاهش تعداد Queryهای دیتابیس استفاده کرد.