我正在使用 Strawberry GraphQL 和 FastAPI 构建 API。我正在考虑提供带有附加到嵌套字段的过滤器的查询,例如:
query {
users {
pets(type: DOG) {
name
}
}
但我找不到实现它的方法。我看到一些例子,类似的问题是通过顶层的过滤器解决的,例如:
query {
users(where: {pets: {type: DOG}) {
pets(type: DOG) {
name
}
}
第一个查询是否是 GraphQL 中允许的模式?如果可以的话,如何在Strawberry中实现呢?
在 GraphQL 中,您提到的第一个查询模式(直接过滤嵌套字段)通常不支持开箱即用。 GraphQL 查询通常设计为在顶层指定过滤器。但是,您可以通过仔细设计架构并使用解析器在 API 中实现类似的功能。
以下是如何为 FastAPI 和 Strawberry GraphQL 设置实施解决方案:
第 1 步:定义模型
假设您有 User 和 Pet 模型,您可能会从以下内容开始:
from typing import List
import strawberry
@strawberry.type
class Pet:
name: str
type: str # You can use an enum for types
@strawberry.type
class User:
id: int
name: str
pets: List[Pet]
第 2 步:定义您的查询类型
接下来,创建一个查询类型,其中包含用户及其宠物的解析器:
@strawberry.type
class Query:
@strawberry.field
def users(self, type: str = None) -> List[User]:
# Replace this with your actual data fetching logic
users_data = [
User(id=1, name="Alice", pets=[Pet(name="Buddy", type="DOG"), Pet(name="Whiskers", type="CAT")]),
User(id=2, name="Bob", pets=[Pet(name="Max", type="DOG")])
]
if type:
for user in users_data:
user.pets = [pet for pet in user.pets if pet.type == type]
return users_data
第 3 步:更新架构
最后,您可以创建架构并将其与 FastAPI 集成:
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
schema = strawberry.federation.Schema(query=Query)
graphql_app = GraphQLRouter(schema)
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
查询示例
通过此设置,您现在可以在顶层查询用户并按类型过滤他们的宠物,如下所示:
query {
users(type: "DOG") {
pets {
name
}
}
}
顶层过滤:由于 GraphQL 不支持直接在查询中过滤嵌套字段,因此我们在用户解析器中提供了一个类型参数。
动态解析器:解析器在返回用户之前根据提供的类型过滤宠物。
此方法遵循 GraphQL 最佳实践,同时仍然允许您达到所需的过滤效果。如果您想要更复杂的嵌套过滤,您可能需要相应地扩展查询参数和逻辑。