30分でFastAPIでGraphQL APIを開発するチュートリアル
はじめに
今回の記事ではデータベースを使わずに、1時間でFastAPIでGraphQL APIを開発する方法を解説する。
対象とする読者
- FastAPIを使っているひと
- これからPythonでGraphQL APIを開発したいひと
- タイトルを見て気になったひと
開発環境
- Windows 11
- Python 3.10.2
- FastAPI
- Strawberry 0.196.2
- Visual Studio Code 1.80
Strawberryとは
Strawberryとは、Pythonで開発されたGraphQL APIのサーバを開発を補助するためのライブラリである。Pythonの型ヒントを使ってGraphQLのスキーマを定義し、APIの開発を助けるためのツールを提供している。
公式サイトによると、FastAPIでGraphQL APIを開発するうえでStrawberryを使うことを推奨している。その理由は以下の通りだ。
- 型安全: StrawberryはPythonの型ヒントを使用してGraphQLスキーマを自動でつくる。これにより、スキーマがPythonコードと常に同期を保ち、型安全が確保される。また、GraphQLの型とPythonの型が一致しているため、バックエンドの開発者が理解しやすくなる。
- 高いパフォーマンス: FastAPIは、Starlette(非同期サーバー)とPydantic(データバリデーションと設定管理を提供するPythonライブラリ)を基に設計されている。これらのコンポーネントにより、FastAPIは高速なパフォーマンスを提供している。Strawberryは同様に非同期処理をサポートしているため、FastAPIと一緒に使用すると、両方のフレームワークの強みが活かされる。
- メンテナンスしやすく読みやすいコードを書ける: Strawberryのコードは読みやすく、保守性が高い。GraphQLのリゾルバはPythonの関数やメソッドとして定義され、それぞれが独立してテストしやすくなっている。
- テストやデバッグが簡単: StrawberryはGraphQL Playgroundという開発ツールを提供しており、APIのテストやデバッグが簡単にできる。これは、クエリの検証やエンドポイントのテストに非常に便利だ。
手順
(1) インストール
まずは、適当に以下のコマンドで新規のディレクトリを作成する。
mkdir sample-api
以下のコマンドを入力する。
pip install fastapi uvicorn[standard] sqlalchemy strawberry-graphql
main.py
に記入する
(2) main.py
を新規で作成して、以下のようにプログラムを書く。
# (1) 必要なライブラリをインポートする
import strawberry
from fastapi import FastAPI
from strawberry.asgi import GraphQL
# (2) User型を定義する
@strawberry.type
class User:
name: str
age: int
# (3) Query(データの読み込み)を行うクラスを定義する
@strawberry.type
class Query:
@strawberry.field
def user(self) -> User:
return User(name="Shota", age=22)
# (4) スキーマを定義する
schema = strawberry.Schema(query=Query)
# (5) GraphQLエンドポイントを作成する
graphql_app = GraphQL(schema)
# (6) FastAPIアプリのインスタンスを作る
app = FastAPI()
# (7) /graphqlでGraphQL APIへアクセスできるようにし、適切なレスポンスを出力
app.add_route("/graphql", graphql_app)
上述のプログラムは名前(name
)と年齢(age
)を出力するだけの簡単なGraphQL APIを出力するものである。
まずは、上述のプログラムの(2)について説明する。
# @strawberry.typeを使うなら忘れない。
import strawberry
@strawberry.type
class User:
name: str
age: int
StrawberryでGraphQLのデータ型を定義する際には、@strawberry.type
を書いた後改行してクラスを定義する。例えば、上述のクラスはGraphQLにおける以下のコードと一致する。
type User {
name: String!
age: Int!
}
次に、(3)のコードを説明する。こちらのコードはQuery
クラスを定義している。Query
クラスはGraphQLのルート型クエリで、GraphQLスキーマのエントリーポイントに該当する。このクラス内のメソッドはGraphQLクエリとして公開され、クライアントがこれらをリクエストで呼び出せるのだ。
@strawberry.type
class Query:
@strawberry.field
def user(self) -> User:
return User(name="Shota", age=22)
上述のuser
メソッドはUser
オブジェクトを出力する。実際のアプリケーションでは、ここでデータベースや他のデータソースからデータを取得するロジックを書くことになる。(今回の記事では取り扱わない)
(4)の部分では、こちらのコードでGraphQLスキーマを定義する。
schema = strawberry.Schema(query=Query)
上述のコードでは、(3)にて定義したQuery
クラスをルートクエリ型として指定している。
(5)から(7)までのコードで、Strawberryで開発したFastAPIのGraphQL APIを立ち上げる処理を行う。
# この処理で、FastAPIアプリケーションと一緒に使えるGraphQLエンドポイントが作られる
graphql_app = GraphQL(schema)
# FastAPIアプリケーションのインスタンスを作成する
app = FastAPI()
# /graphqlパスにGraphQLアプリケーションを追加する
app.add_route("/graphql", graphql_app)
上述のコードの結果、クライアントは/graphql
エンドポイントに対してGraphQLクエリを送信しUser
型のuser
フィールドを取得できる。
(3) サーバを立ち上げる
以下のコマンドを入力する。
uvicorn main:app --reload
上述のコマンドを入力後、以下のメッセージが出力されたら問題なく実行されている。Application startup complete.
が重要なキーワードだ。
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [14400] using statreload
INFO: Started server process [17288]
INFO: Waiting for application startup.
INFO: Application startup complete.
こちらのコマンドを入力すると、GraphQL APIを開発・操作できるエディタGraphiQLにアクセスできる。(以下の画像を参照)
そして、こちらのquery
を左側のエディタに入力することで、以下のように出力される。
query {
user {
name
age
}
}
出力結果の画像。右側に出力される。
出力されたJSONレスポンスは以下の通り。
{
"data": {
"user": {
"name": "Shota",
"age": 22
}
}
}
これで簡単なGraphQL APIが完成する。
参考サイト
Discussion