ایجاد Query ساده برای User و Task و اتصال به FastAPI

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

ایجاد Query ساده برای User و Task

در این مرحله، ابتدا Queryهای ساده‌ای تعریف می‌کنیم تا بتوانیم کاربران و تسک‌ها را از دیتابیس بخوانیم. هدف این است که یک پایه برای Mutationها فراهم کنیم. تغییرات فقط در بخش GraphQL اضافه می‌شوند و بقیه اپ نیاز به تغییر ندارد.

# graphql/users.py
import strawberry
from models.users import User as UserModel
from sqlalchemy.orm import Session
from typing import List

from graphql.tasks import TaskType  # برای نمایش تسک‌ها مرتبط با کاربر

@strawberry.type
class UserType:
    id: int
    email: str
    created_at: str
    updated_at: str | None
    tasks: list[TaskType] | None  # رابطه یک به چند با Task

@strawberry.type
class UserQuery:
    @strawberry.field
    def users(self, info) -> List[UserType]:
        db: Session = info.context["db"]
        users = db.query(UserModel).all()
        result = []
        for u in users:
            result.append(
                UserType(
                    id=u.id,
                    email=u.email,
                    created_at=str(u.created_at),
                    updated_at=str(u.updated_at),
                    tasks=[TaskType(
                        id=t.id,
                        title=t.title,
                        description=t.description,
                        is_completed=t.is_completed,
                        created_at=str(t.created_at),
                        updated_at=str(t.updated_at),
                        owner_id=t.owner_id
                    ) for t in u.tasks] if hasattr(u, "tasks") else []
                )
            )
        return result
# graphql/tasks.py
import strawberry
from models.tasks import Task as TaskModel
from sqlalchemy.orm import Session
from typing import List

@strawberry.type
class TaskType:
    id: int
    title: str
    description: str | None
    is_completed: bool
    created_at: str
    updated_at: str | None
    owner_id: int

@strawberry.type
class TaskQuery:
    @strawberry.field
    def tasks(self, info) -> List[TaskType]:
        db: Session = info.context["db"]
        tasks = db.query(TaskModel).all()
        return [
            TaskType(
                id=t.id,
                title=t.title,
                description=t.description,
                is_completed=t.is_completed,
                created_at=str(t.created_at),
                updated_at=str(t.updated_at),
                owner_id=t.owner_id
            ) for t in tasks
        ]

توضیح

  • Query users تمام کاربران را برمی‌گرداند و شامل لیست تسک‌های هر کاربر است.
  • Query tasks تمام تسک‌ها را برمی‌گرداند.
  • در این مرحله هنوز Mutation نداریم، بنابراین داده‌ها فقط خوانده می‌شوند.

ایجاد Mutation ساده برای ثبت کاربر

# graphql/users.py (ادامه)
from models.users import User as UserModel
from config.database import SessionLocal

@strawberry.type
class UserMutation:
    @strawberry.mutation
    def create_user(self, info, email: str, password: str) -> UserType:
        db: Session = info.context["db"]
        new_user = UserModel(email=email, password=password)
        db.add(new_user)
        db.commit()
        db.refresh(new_user)
        return UserType(
            id=new_user.id,
            email=new_user.email,
            created_at=str(new_user.created_at),
            updated_at=str(new_user.updated_at),
            tasks=[]
        )

ایجاد Mutation ساده برای ثبت Task مرتبط با کاربر

# graphql/tasks.py (ادامه)
from models.tasks import Task as TaskModel
from config.database import SessionLocal

@strawberry.type
class TaskMutation:
    @strawberry.mutation
    def create_task(self, info, title: str, owner_id: int, description: str | None = None) -> TaskType:
        db: Session = info.context["db"]
        new_task = TaskModel(title=title, owner_id=owner_id, description=description)
        db.add(new_task)
        db.commit()
        db.refresh(new_task)
        return TaskType(
            id=new_task.id,
            title=new_task.title,
            description=new_task.description,
            is_completed=new_task.is_completed,
            created_at=str(new_task.created_at),
            updated_at=str(new_task.updated_at),
            owner_id=new_task.owner_id
        )

توضیح

  • ابتدا یک کاربر ایجاد می‌کنیم تا Task بتواند به آن متصل شود.
  • برای ایجاد Task، شناسه کاربر (owner_id) باید مشخص شود.
  • در این مرحله Queryها برای خواندن داده‌ها و Mutationها برای ایجاد داده‌ها آماده هستند و می‌توان تست کرد.

نحوه اتصال GraphQL Schema به FastAPI

بعد از تعریف Query و Mutation برای User و Task، باید Schema نهایی را بسازیم و آن را به یک مسیر GraphQL در FastAPI متصل کنیم. در این بخش، فقط بخش‌های مرتبط با GraphQL تغییر می‌کنند و بقیه اپ (مثل دیتابیس یا مدل‌ها) نیازی به تغییر ندارد.

# schema.py
import strawberry
from graphql.users import UserQuery, UserMutation
from graphql.tasks import TaskQuery, TaskMutation

@strawberry.type
class Query(UserQuery, TaskQuery):
    pass

@strawberry.type
class Mutation(UserMutation, TaskMutation):
    pass

schema = strawberry.Schema(query=Query, mutation=Mutation)

حالا این Schema را در FastAPI به GraphQLRouter متصل می‌کنیم:

# main.py
from strawberry.fastapi import GraphQLRouter
from schema import schema
from config.database import get_db

# اتصال GraphQL
graphql_app = GraphQLRouter(
    schema,
    context_getter=lambda request: {"db": next(get_db())}
)
app.include_router(graphql_app, prefix="/graphql")

@app.get("/")
def root():
    return {"message": "FastAPI + GraphQL is ready!"}

توضیح

  • Router مربوط به GraphQL با GraphQLRouter ساخته می‌شود.
  • Schema که شامل Query و Mutation است به Router داده می‌شود.
  • با استفاده از context_getter، Session دیتابیس به Resolverها منتقل می‌شود.

ثبت دیدگاه


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

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


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