はじめに
本記事は、自分の備忘録も兼ねて書いてます。
前回は、GraphQLの仕組み(スキーマ、クエリ、リゾルバ)について解説しました。
今回は、実際にPythonを使って、簡易的なGraphQLサーバーを構築し、動かしてみます。
ライブラリには、スキーマ駆動開発(Schema-First)と相性の良い Ariadne(アリアドネ)を使用します。
【動作環境】
- Python: 3.x
- Flask: Webサーバーフレームワーク
- Ariadne: GraphQLライブラリ
まずは必要なライブラリをインストールします。
pip install Flask ariadne
サーバーの実装
第1回〜第3回で使用した「ユーザー」と「記事」の例を、実際にGraphQLで実装します。
ファイル名は graphql_server.py とします。
from flask import Flask, request, jsonify
from ariadne import ObjectType, QueryType, make_executable_schema, load_schema_from_path
from ariadne.explorer import ExplorerGraphiQL
# 1. スキーマ定義 (SDL)
# 本来は別ファイル(.graphql)に書くことが多いですが、今回は文字列で定義します。
type_defs = """
type Query {
user(id: ID!): User
post(id: ID!): Post
}
type User {
id: ID!
name: String!
email: String
}
type Post {
id: ID!
title: String!
author: User!
comments: [Comment]
}
type Comment {
id: ID!
text: String!
}
"""
# --- サンプルデータ ---
users_data = {
"1": {"id": "1", "name": "佐藤 太郎", "email": "taro@example.com"},
"2": {"id": "2", "name": "鈴木 花子", "email": "hanako@example.com"},
}
posts_data = {
"p1": {"id": "p1", "author_id": "1", "title": "GraphQL入門"},
"p2": {"id": "p2", "author_id": "2", "title": "Flaskの使い方"},
}
comments_data = {
"p1": [{"id": "c1", "text": "分かりやすい"}, {"id": "c2", "text": "勉強になる"}],
"p2": [{"id": "c3", "text": "試してみます"}],
}
# 2. リゾルバの実装
query = QueryType()
@query.field("user")
def resolve_user(*_, id):
return users_data.get(id)
@query.field("post")
def resolve_post(*_, id):
return posts_data.get(id)
# Post型のためのリゾルバ(ネストしたデータの解決)
post = ObjectType("Post")
@post.field("author")
def resolve_post_author(post_obj, *_):
# post_obj は親データ(この記事データ)
return users_data.get(post_obj["author_id"])
@post.field("comments")
def resolve_post_comments(post_obj, *_):
return comments_data.get(post_obj["id"])
# 3. 実行可能なスキーマの作成
schema = make_executable_schema(type_defs, query, post)
# 4. Flaskアプリの作成
app = Flask(__name__)
explorer_html = ExplorerGraphiQL().html(None)
@app.route("/graphql", methods=["GET"])
def graphql_playground():
# ブラウザでアクセスしたときはPlaygroundを表示
return explorer_html, 200
@app.route("/graphql", methods=["POST"])
def graphql_server():
# POSTリクエスト(クエリ)を処理
data = request.get_json()
success, result = schema.execute_sync(
data.get("query"),
variable_values=data.get("variables"),
)
status_code = 200 if success else 400
return jsonify(result), status_code
if __name__ == "__main__":
app.run(debug=True, port=5000)
実行と確認
サーバーを起動します。
python graphql_server.py
ブラウザでの確認 (GraphQL Playground)
ブラウザで http://127.0.0.1:5000/graphql にアクセスしてください。
Ariadneには標準で GraphiQL (開発者ツール) が組み込まれています。
左側のエディタに以下のクエリを入力し、再生ボタン(▶)を押してみましょう。
query {
post(id: "p1") {
title
author {
name
}
comments {
text
}
}
}
右側に、期待通りのJSONデータが返ってくるはずです。
{
"data": {
"post": {
"title": "GraphQL入門",
"author": {
"name": "佐藤 太郎"
},
"comments": [
{ "text": "分かりやすい" },
{ "text": "勉強になる" }
]
}
}
}
これが、第3回で解説した「アンダーフェッチの解決」が実際に動いている様子です。
1回のリクエストで、記事・著者・コメントをまとめて取得できています。
まとめ
- Pythonの
Ariadneライブラリを使うと、スキーマ定義(SDL)とリゾルバ関数を紐付けるだけでGraphQLサーバーが作れる -
ObjectTypeを使って、ネストしたデータ(記事の著者など)のリゾルバを個別に定義できる - 開発者ツール(GraphiQL)を使うと、クエリのテストが簡単にできる
これで、GraphQLの基本的な流れを解説しました。