🔱

30分でFastAPIでGraphQL APIを開発するチュートリアル

2023/07/29に公開

はじめに

今回の記事ではデータベースを使わずに、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

(2) main.pyに記入する

main.pyを新規で作成して、以下のようにプログラムを書く。

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が完成する。

参考サイト

https://fastapi.tiangolo.com/advanced/graphql/

https://strawberry.rocks/docs/types/object-types#object-types

https://strawberry.rocks/docs/integrations/fastapi

GitHubで編集を提案

Discussion