CodeWalk

GraphQL Python实现:Ariadne/Strawberry原理与对比

作者:孤独的心 · 2026-05-30 12:55

请介绍Python中实现GraphQL服务的主要库:Ariadne(Schema-first)和Strawberry(Code-first)的核心用法和设计哲学差异。给出一个简易用户查询的GraphQL Schema定义和Resolver实现。对比REST API与GraphQL在数据获取效率上的区别,以及N+1查询问题在GraphQL中的解决方案(DataLoader)。

回答

孤独的心

Ariadne(Schema-first):先写SDL再绑Resolver。

# schema.graphql
"""
type Query {
    user(id: ID!): User
    users: [User!]!
}
type User {
    id: ID!
    name: String!
    posts: [Post!]!
}
"""

# resolvers.py
from ariadne import QueryType, gql, make_executable_schema

query = QueryType()

@query.field('user')
def resolve_user(_, info, id):
    return db.get_user(id)

schema = make_executable_schema(gql(open('schema.graphql').read()), query)

Strawberry(Code-first):用Python类型定义Schema。

import strawberry

@strawberry.type
class User:
    id: strawberry.ID
    name: str
    
@strawberry.type
class Query:
    @strawberry.field
    def user(self, id: strawberry.ID) -> User:
        return db.get_user(id)

schema = strawberry.Schema(query=Query)

REST vs GraphQL

  • REST:多端点,客户端无法精确控制返回字段(over-fetching/under-fetching)
  • GraphQL:单端点,客户端指定所需字段,减少网络传输

N+1解决方案(DataLoader)

from ariadne.utils import convert_kwargs_to_snake_case
from promise import Promise
from promise.dataloader import DataLoader

class UserLoader(DataLoader):
    def batch_load_fn(self, ids):
        users = db.get_users_by_ids(ids)
        return Promise.resolve([users.get(id) for id in ids])

@query.field('users')
def resolve_users(_, info):
    info.context['user_loader'] = UserLoader()

对比总结:Ariadne适合GraphQL先行的团队;Strawberry适合Pythonic代码优先、类型安全的项目。