GraphQL subscriptions are a way to establish a long - lived connection between the client and the server using WebSockets. Unlike queries and mutations, which are typically one - time requests, subscriptions allow the server to push data to the client whenever a specific event occurs. For example, in a chat application, a subscription can be used to receive new messages as soon as they are sent.
FastAPI is built on top of Starlette and Pydantic. It uses Python type hints to validate, serialize, and deserialize data. FastAPI is known for its high performance due to its asynchronous nature and the use of modern Python features. It also provides automatic API documentation generation, which makes it easy for developers to understand and use the API.
First, create a virtual environment and install the necessary packages:
python -m venv venv
source venv/bin/activate
pip install fastapi uvicorn
Create a basic FastAPI application in a file named main.py
:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
To run the application, use the following command:
uvicorn main:app --reload
Strawberry is a Python library for creating GraphQL APIs. Install it using pip
:
pip install strawberry-graphql[fastapi]
Modify the main.py
file to add GraphQL support:
import strawberry
from fastapi import FastAPI
from strawberry.asgi import GraphQL
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello, GraphQL!"
schema = strawberry.Schema(query=Query)
app = FastAPI()
app.add_route("/graphql", GraphQL(schema))
app.add_websocket_route("/graphql", GraphQL(schema))
Let’s implement a simple subscription that sends a counter value every second.
import asyncio
import strawberry
from fastapi import FastAPI
from strawberry.asgi import GraphQL
@strawberry.type
class Subscription:
@strawberry.subscription
async def counter(self) -> int:
count = 0
while True:
yield count
count += 1
await asyncio.sleep(1)
@strawberry.type
class Query:
@strawberry.field
def hello(self) -> str:
return "Hello, GraphQL!"
schema = strawberry.Schema(query=Query, subscription=Subscription)
app = FastAPI()
app.add_route("/graphql", GraphQL(schema))
app.add_websocket_route("/graphql", GraphQL(schema))
When working with GraphQL subscriptions, it’s important to handle WebSocket connections properly. FastAPI and Strawberry take care of most of the low - level details, but you may need to handle connection errors, disconnections, and authentication. For example, you can add middleware to the WebSocket route to handle authentication:
from fastapi import WebSocket
from strawberry.asgi import GraphQL
async def websocket_middleware(ws: WebSocket, next):
# Implement authentication logic here
await next(ws)
graphql_app = GraphQL(schema)
graphql_app.add_websocket_middleware(websocket_middleware)
app.add_websocket_route("/graphql", graphql_app)
You can use tools like graphql - ws - test
to test GraphQL subscriptions. Another option is to use a GraphQL client like Apollo Client or Relay. In a development environment, you can also use the GraphQL Playground provided by Strawberry to test subscriptions interactively.
Proper error handling is crucial when dealing with GraphQL subscriptions. You should catch and handle exceptions in the subscription resolver functions. For example:
@strawberry.subscription
async def counter(self) -> int:
try:
count = 0
while True:
yield count
count += 1
await asyncio.sleep(1)
except Exception as e:
# Log the error
print(f"Error in subscription: {e}")
# You can also send an error message to the client
To ensure scalability and performance, use an asynchronous database driver if you are fetching data from a database. Also, consider using a message queue like Redis or RabbitMQ to handle events that trigger subscriptions. This can help distribute the load and prevent bottlenecks.
Integrating GraphQL subscriptions with FastAPI allows developers to build real - time, reactive applications with ease. By understanding the fundamental concepts, following the usage methods, common practices, and best practices, you can create high - performance, scalable applications. FastAPI’s asynchronous nature and GraphQL’s flexibility make them a powerful combination for modern web development.