Strawberry(Python)とは?型安全なGraphQLライブラリの使い方を実装例で解説
Strawberryは、Pythonの型ヒントでGraphQLスキーマを書けるライブラリです。@strawberry.typeを付けたクラスがそのままGraphQLの型になり、mypyやエディタ補完がスキーマ定義に効くのが最大の特徴です。この記事では、Strawberryの位置づけと定番のGrapheneとの使い分け、対応Pythonバージョンとインストールを押さえます。さらに、スキーマ定義からresolver・FastAPI/Django統合・GraphiQLでのクエリ実行、本番で必ず問題になるN+1対策までを、動く実装例つきで整理します。バージョンは2026年7月時点の最新版0.321.0を前提にしています。
まとめ:Strawberryを使う前に押さえる要点
- 正体:Python製のGraphQLサーバライブラリ。実行エンジンはGrapheneと同じ
graphql-coreで、違いはスキーマの書き方(型ヒント方式かクラス継承方式か)。 - 対応環境:最新の0.321.0はPython 3.10以上(
>=3.10, <4.0)。3.9以前は非対応になったため、公式の「3.7以降」表記は古い。 - 導入:
pip install strawberry-graphql。FastAPI・Django統合や開発サーバは追加パッケージ/extraで入れる。 - 選び方:新規開発でFastAPIや型安全を重視するならStrawberry。既存のGraphene資産やRelay中心の構成が大きいなら無理に移行しない。
- 本番の勘所:ネストクエリのN+1はDataLoaderで束ね、公開APIはクエリ深度・複雑度を制限する。
Strawberryとは:型ヒントで書くPython製GraphQLライブラリ
Strawberryは、PythonでGraphQL APIのサーバ側を実装するためのライブラリです。GraphQLの型・クエリ・ミューテーションを、いずれもPythonのクラスと型アノテーションとして記述します。strやintといった型ヒントがそのままGraphQLのスカラー型に対応し、フィールドの戻り値型がスキーマに反映されるため、コードとスキーマの二重管理が要りません。型情報が揃うことで、mypyによる静的チェックやIDEの補完がスキーマ定義そのものに効きます。
誤解されやすい点として、Strawberryは自前のGraphQLパーサや実行エンジンを持っているわけではありません。クエリの解析・検証・実行はgraphql-core(GraphQL-core 3)に委ねており、これは後述するGrapheneと共通の土台です。Strawberryが提供しているのは、その上に載る「型ヒントベースでスキーマを書く層」です。したがって「依存が少ないから軽い」という説明は正確ではなく、比較すべきは依存の多寡ではなくスキーマの記述スタイルだと理解しておくと選定を誤りません。GraphQLそのものの考え方やREST APIとの違いはGraphQLとは?REST APIとの違い・メリット・デメリットをわかりやすく解説で補完できます。
StrawberryとGrapheneの違いと使い分け
PythonのGraphQLライブラリで比較対象になるのは、長く使われてきたGrapheneです。両者ともgraphql-coreの上に構築されており、GraphQL仕様への準拠という点で差はありません。分かれるのは、スキーマをどう書くかという開発体験です。
| 観点 | Strawberry | Graphene |
|---|---|---|
| スキーマ定義 | 型ヒント+デコレータ | クラス継承(Meta等) |
| 型チェック | mypyがそのまま効く | 型ヒント前提でない |
| async対応 | 標準でasync resolver可 | 限定的・別途対応が必要 |
| 実行エンジン | graphql-core 3(共通) | |
| 開発の活発さ | 更新頻度が高い | 近年は更新が緩やか |
Grapheneはクラス継承で型を組み立てるため、GraphQLの型システムに素直な一方、型ヒントによる静的チェックの恩恵は薄くなります。StrawberryはUserのようなデータクラスに近い記述で済み、返り値型の食い違いを実行前に検出できます。
使い分けの判断はシンプルです。新規開発で、FastAPIと組み合わせたい、あるいはmypyでの型安全を重視するならStrawberryを選びます。逆に、既存のGrapheneベースのスキーマが大きい、Relayのグローバルノード仕様に深く依存しているといった場合は、移行コストに見合わないため無理にStrawberryへ乗り換える必要はありません。型安全という一点だけで既存資産を捨てるのは、実務では割に合わないことが多いからです。
Strawberryの導入:対応Pythonバージョンとインストール
最新のstrawberry-graphql 0.321.0(2026年7月時点)が要求するPythonは>=3.10, <4.0で、動作対象は3.10・3.11・3.12・3.13です(要件上は3.14も範囲に含みます)。かつて案内されていた「Python 3.7以降」はすでに対象外で、3.9以前でインストールすると依存解決に失敗します。導入前にまずpython --versionで3.10以上かを確認してください。
インストールはプロジェクトごとの仮想環境で行います。標準のvenvで環境を作り、有効化してから入れます。
python -m venv venv
source venv/bin/activate # Windowsは venv\Scripts\activate
pip install strawberry-graphql
ブラウザ上でクエリを試せる開発サーバまで含めたいときはpip install "strawberry-graphql[debug-server]"のようにextraを指定します。FastAPIやDjangoと統合する場合は、それぞれstrawberry-graphql[fastapi]、Django向けのモデル連携パッケージstrawberry-graphql-djangoを追加します。pip freeze > requirements.txtで依存を固定しておけば、チームや本番環境で同じ構成を再現できます。
スキーマ定義とresolverの実装
Strawberryの中心は、型・クエリ・resolverをPythonのクラスと関数で書くことです。ここでは定義の基本、更新系のMutation、非同期resolverの順に分けて示します。
型とQueryの定義(@strawberry.type / @strawberry.field)
@strawberry.typeを付けたクラスがGraphQLの型になります。フィールドは属性の型ヒントで表現し、値を返すresolverは@strawberry.fieldを付けたメソッドとして書きます。
import strawberry
@strawberry.type
class User:
id: int
name: str
@strawberry.type
class Query:
@strawberry.field
def user(self) -> User:
return User(id=1, name="Ann")
戻り値の型-> Userがそのままスキーマ上のフィールド型になります。型を書き間違えればmypyが指摘するため、スキーマと実装の乖離を実行前に潰せます。ネストは型の属性に別の型を持たせるだけで表現でき、GraphQLの部分取得(必要なフィールドだけ要求する)にそのまま対応します。
Mutationとresolverの記述
データの作成・更新・削除は@strawberry.mutationで定義します。引数も型ヒントで宣言でき、入力の型はスキーマ側のバリデーションに使われます。
@strawberry.type
class Mutation:
@strawberry.mutation
def create_user(self, name: str) -> User:
return User(id=2, name=name)
schema = strawberry.Schema(query=Query, mutation=Mutation)
QueryとMutationをstrawberry.Schemaにまとめたschemaが、以降のサーバ統合で共通して使う実体になります。
非同期(async)resolverとDB接続
resolverはasync defで書けます。データベースや外部APIへのI/O待ちを非同期化することで、リクエストごとにスレッドをブロックせずに処理できます。
@strawberry.type
class Query:
@strawberry.field
async def user(self, id: int) -> User:
return await fetch_user(id)
実務ではhttpxや非同期対応のORMと組み合わせ、resolver内でDBや外部サービスから取得した結果を型にマッピングして返します。非同期resolverはFastAPIと組み合わせたときに本領を発揮します。
FastAPI・Djangoとの統合
Strawberryは単体でも動きますが、実運用では既存のWebフレームワークに載せます。FastAPIとDjangoで統合方法が異なります。
FastAPIと統合する(GraphQLRouter)
FastAPIではstrawberry.fastapiのGraphQLRouterにスキーマを渡し、ルータとして組み込みます。非同期resolverをそのまま活かせるのがこの構成の利点です。
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
graphql_app = GraphQLRouter(schema)
app = FastAPI()
app.include_router(graphql_app, prefix="/graphql")
これで/graphqlにGraphQLエンドポイントが生えます。FastAPIの依存性注入(Depends)を使えば、認証やDBセッションをresolverへ渡す構成も自然に組めます。FastAPI側の基本はFastAPIとは|最短で動かす手順とasync/defの使い分けを参照してください。
Djangoと統合する(GraphQLView・strawberry-graphql-django)
Djangoではstrawberry.django.viewsのGraphQLView(非同期ならAsyncGraphQLView)をurls.pyに登録します。POSTでクエリを受けるため、csrf_exemptを併用するのが定石です。
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from strawberry.django.views import GraphQLView
from .schema import schema
urlpatterns = [
path("graphql/", csrf_exempt(GraphQLView.as_view(schema=schema))),
]
Djangoモデルをスキーマへ落とし込みたい場合は、別パッケージのstrawberry-graphql-django(インポート名はstrawberry_django)を使うと、モデル定義から型を生成できます。既存のDjangoアプリの詳細はDjangoとは何か?Djangoの主な特徴と利点にまとめています。
サーバ起動とGraphiQLでのクエリ実行
FastAPI構成なら、ASGIサーバのuvicornで起動します。main.pyにappを定義している場合は次のコマンドです。
uvicorn main:app --reload
フレームワークに載せず単体で動作確認したいだけなら、[debug-server] extraを入れたうえでstrawberry server mainのように起動する方法もあります。起動後、ブラウザでエンドポイントを開くとGraphiQL(対話的なクエリ実行UI)が表示されます。ここで補完を効かせながらクエリを組み立て、送信結果を即座に確認できます。たとえば先ほどのuserクエリはこう書きます。
query {
user {
id
name
}
}
Mutationも同じUIから実行でき、型の不一致や引数名の誤りはレスポンスのエラーメッセージに具体的に出るため、原因の切り分けが容易です。GraphiQLはフロントエンド担当者へAPI仕様を共有する場としても使えます。GraphiQL上で必要なフィールドだけを選ぶ書き方はGraphQLのFragmentとは?基礎概念、役割、定義方法とメリットで整理しています。
本番運用で注意すべき点:N+1問題とクエリ深度制限
入門記事では触れられにくいものの、GraphQLを本番に出すとほぼ必ず直面するのが、ネストクエリの性能問題と、柔軟すぎるクエリによる負荷です。Strawberryにはどちらにも標準的な対処手段があります。
N+1問題とDataLoaderでの解決
「ユーザー一覧+各ユーザーの所属」のようなネストクエリでは、素直に実装すると親1回+子N回のクエリが飛ぶN+1問題が起きます。Strawberryはstrawberry.dataloader.DataLoaderを提供しており、同一リクエスト内の複数キーをまとめて1回で解決できます。
from strawberry.dataloader import DataLoader
async def load_users(keys: list[int]) -> list[User]:
rows = await fetch_users(keys)
return [rows[k] for k in keys]
loader = DataLoader(load_fn=load_users)
resolverからはawait loader.load(id)で個別に呼び出しても、内部でキーが束ねられ、DBアクセスは1回に集約されます。件数が増えても発行クエリ数が線形に膨らまない設計にできるのが要点です。
クエリ深度・複雑度の制限とセキュリティ
GraphQLはクライアントが自由にクエリを組めるため、深くネストしたクエリでサーバを疲弊させる攻撃が成立し得ます。Strawberryでは拡張機能QueryDepthLimiterをスキーマに渡すことで、許容する最大深度を制限できます。
from strawberry.extensions import QueryDepthLimiter
schema = strawberry.Schema(
query=Query,
extensions=[QueryDepthLimiter(max_depth=10)],
)
深度制限に加え、公開APIでは認証・認可をresolverまたはミドルウェアで必ず挟み、想定を超える件数取得にはページングを強制します。開発中はGraphiQLで自由に叩けて便利ですが、本番環境ではイントロスペクションの扱いも含めて公開範囲を絞るのが安全です。
よくある質問(FAQ)
Strawberryの対応Pythonバージョンは?
最新の0.321.0はPython 3.10以上(>=3.10, <4.0)が対象で、3.10〜3.13が検証されています。3.9以前は非対応で、旧ドキュメントの「3.7以降」という記載は現行版には当てはまりません。導入前に3.10以上であることを確認してください。
StrawberryとGrapheneはどちらを選ぶべき?
新規開発で型安全やFastAPI連携を重視するならStrawberryが有力です。両者ともgraphql-coreを土台にしており仕様面の差はないため、既存のGrapheneコードが多い場合は移行コストを優先して現状維持でも問題ありません。
StrawberryにGraphQLクライアント機能はある?
Strawberryはサーバ側を作るライブラリで、クエリを送る側のクライアント機能は含みません。フロントからの呼び出しには、JavaScript側のApollo ClientやurqlなどのGraphQLクライアント、あるいは検証用のGraphiQLを使います。
StrawberryはFastAPIとDjangoのどちらと相性がいい?
非同期resolverをそのまま活かせる点でFastAPIとの親和性が高いですが、DjangoでもAsyncGraphQLViewとモデル連携パッケージで実用的に統合できます。既存プロジェクトが使っているフレームワークに合わせるのが基本です。
GraphiQLはどうやって開く?
FastAPIやDjangoに統合したうえでサーバを起動し、ブラウザでGraphQLエンドポイントのURLへアクセスすると自動でGraphiQLのUIが表示されます。そこでクエリの入力・送信・結果確認ができます。