GraphQL入門!
RESTとの違いと基本的な使い方
GraphQLは必要なデータを必要な分だけ取得できるAPIクエリ言語です。RESTとの比較を交えて解説します。
こんな人向けの記事です
- GraphQLの基本概念を理解したい人
- REST APIの課題を感じている人
- 効率的なAPI設計を学びたい人
Step 1GraphQLとは
GraphQLはFacebookが開発したAPIのクエリ言語です。クライアントが必要なデータの構造を指定してリクエストします。
GraphQLの特徴
# GraphQLの3つの特徴
# 1. 必要なデータだけ取得(Over-fetching解消)
# REST: GET /users/1 → 全フィールドが返る
# GraphQL: { user(id: 1) { name email } } → name と email だけ返る
# 2. 1回のリクエストで複数リソース取得(Under-fetching解消)
# REST: GET /users/1 → GET /users/1/posts → GET /users/1/followers
# GraphQL: 1回のクエリで全て取得可能
# 3. 型システムによる自己文書化
# スキーマがそのままAPIのドキュメントになるStep 2RESTとの比較
REST vs GraphQL
# === REST API ===
# 複数のエンドポイント
# GET /api/users/1
# GET /api/users/1/posts
# GET /api/users/1/followers
# レスポンス(不要なデータも含まれる)
# {
# "id": 1, "name": "田中", "email": "...",
# "address": "...", "phone": "...", ← 不要かも
# "created_at": "..."
# }
# === GraphQL ===
# 単一エンドポイント: POST /graphql
# クエリで必要なデータだけ指定
# {
# user(id: 1) {
# name
# posts { title }
# followers { name }
# }
# }
# レスポンス(リクエストした構造そのまま)
# {
# "data": {
# "user": {
# "name": "田中",
# "posts": [{"title": "記事1"}, {"title": "記事2"}],
# "followers": [{"name": "佐藤"}, {"name": "鈴木"}]
# }
# }
# }どちらを選ぶ?
シンプルなCRUD APIならREST、複雑なデータ関係や多様なクライアント(Web/モバイル)がある場合はGraphQLが有利です。Step 3クエリの基本
GraphQLクエリ
# 基本クエリ
query {
user(id: 1) {
name
email
}
}
# 複数リソースの同時取得
query {
user(id: 1) {
name
posts(limit: 5) {
title
createdAt
}
}
recentArticles(limit: 3) {
title
author { name }
}
}
# 変数を使ったクエリ
query GetUser($userId: ID!, $postLimit: Int = 10) {
user(id: $userId) {
name
email
posts(limit: $postLimit) {
title
content
comments {
body
author { name }
}
}
}
}
# 変数: { "userId": "1", "postLimit": 5 }
# フラグメント(再利用可能なフィールドセット)
fragment UserBasic on User {
id
name
email
}
query {
user(id: 1) { ...UserBasic }
admin: user(id: 99) { ...UserBasic role }
}Step 4ミューテーション(データ変更)
GraphQLミューテーション
# データの作成
mutation {
createUser(input: {
name: "田中太郎"
email: "tanaka@example.com"
}) {
id
name
email
}
}
# データの更新
mutation {
updateUser(id: 1, input: {
name: "田中一郎"
}) {
id
name
}
}
# データの削除
mutation {
deleteUser(id: 1) {
success
message
}
}
# 変数を使ったミューテーション
mutation CreatePost($input: PostInput!) {
createPost(input: $input) {
id
title
author { name }
}
}
# 変数: { "input": { "title": "新記事", "content": "本文" } }Step 5スキーマ定義
GraphQLスキーマ(SDL)
# 型定義
type User {
id: ID! # !は必須(Non-null)
name: String!
email: String!
age: Int
posts: [Post!]! # Postの配列(必須)
createdAt: String!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
body: String!
author: User!
}
# 入力型(ミューテーション用)
input CreateUserInput {
name: String!
email: String!
age: Int
}
# クエリとミューテーションの定義
type Query {
user(id: ID!): User
users(limit: Int = 10, offset: Int = 0): [User!]!
post(id: ID!): Post
}
type Mutation {
createUser(input: CreateUserInput!): User!
updateUser(id: ID!, input: CreateUserInput!): User!
deleteUser(id: ID!): Boolean!
}
# Enum型
enum Role {
ADMIN
USER
GUEST
}Step 6実践:PythonでGraphQLサーバー
Python(Strawberry + FastAPI)
# pip install strawberry-graphql fastapi uvicorn
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
# 型定義
@strawberry.type
class User:
id: int
name: str
email: str
# サンプルデータ
users_db = [
User(id=1, name="田中太郎", email="tanaka@example.com"),
User(id=2, name="佐藤花子", email="sato@example.com"),
]
# クエリ
@strawberry.type
class Query:
@strawberry.field
def users(self) -> list[User]:
return users_db
@strawberry.field
def user(self, id: int) -> User | None:
return next((u for u in users_db if u.id == id), None)
# ミューテーション
@strawberry.type
class Mutation:
@strawberry.mutation
def create_user(self, name: str, email: str) -> User:
new_id = max(u.id for u in users_db) + 1
user = User(id=new_id, name=name, email=email)
users_db.append(user)
return user
schema = strawberry.Schema(query=Query, mutation=Mutation)
app = FastAPI()
app.include_router(GraphQLRouter(schema), prefix="/graphql")
# uvicorn main:app → http://localhost:8000/graphqlGraphiQL
Strawberryには開発用のGraphiQL(グラフィクル)UIが組み込まれており、ブラウザでクエリを試せます。まとめ
- GraphQLは必要なデータだけを1回のリクエストで取得
- Over-fetching/Under-fetchingを解消
- Query(読み取り)とMutation(変更)の2種類の操作
- スキーマ(型定義)がAPIドキュメントになる
- PythonではStrawberry + FastAPIで簡単に構築