GraphQL¶
FastHTTP supports GraphQL queries and mutations through the @app.graphql() decorator.
Introduction¶
GraphQL is a query language for APIs that allows clients to request exactly the data they need. FastHTTP provides a convenient decorator for working with GraphQL endpoints.
Usage¶
Query (reading data)¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.graphql(url="https://api.example.com/graphql")
async def get_user(resp: Response) -> dict:
return {"query": "{ user(id: 1) { name email } }"}
Mutation (writing data)¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.graphql(url="https://api.example.com/graphql", operation_type="mutation")
async def create_user(resp: Response) -> dict:
return {
"query": "mutation { createUser(name: $name) { id name } }",
"variables": {"name": "John"}
}
Decorator Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
str |
— | GraphQL endpoint URL (required) |
operation_type |
str |
"query" |
Operation type: "query" or "mutation" |
headers |
dict |
None |
Additional headers |
timeout |
float |
30.0 |
Request timeout in seconds |
tags |
list |
None |
Tags for grouping requests |
response_model |
type[BaseModel] |
None |
Pydantic model for response validation |
dependencies |
list |
None |
List of dependencies |
Return Dictionary Parameters¶
The handler function must return a dictionary with the following keys:
| Key | Type | Description |
|---|---|---|
query |
str |
GraphQL query (required) |
variables |
dict |
Query variables |
operation_name |
str |
Operation name (if multiple) |
Data Types¶
GraphQLResponse¶
Represents the response from a GraphQL server:
from fasthttp.graphql import GraphQLResponse
response = GraphQLResponse(
data={"user": {"name": "John"}},
errors=None,
extensions={"traceId": "abc123"}
)
# Check for errors
if response.ok:
print(response.data)
elif response.has_errors:
print(response.errors)
GraphQLResponse properties:
| Property | Type | Description |
|---|---|---|
data |
dict \| None |
Response data |
errors |
list \| None |
List of errors |
extensions |
dict \| None |
Additional data |
ok |
bool |
True if no errors |
has_errors |
bool |
True if has errors |
Examples¶
Creating a user¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.graphql(url="https://api.example.com/graphql", operation_type="mutation")
async def create_user(resp: Response) -> dict:
return {
"query": """
mutation CreateUser($name: String!, $email: String!) {
createUser(name: $name, email: $email) {
id
name
email
}
}
""",
"variables": {
"name": "John Doe",
"email": "john@example.com"
}
}
if __name__ == "__main__":
app.run()
Getting a list with filtering¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.graphql(url="https://api.example.com/graphql")
async def get_users(resp: Response) -> dict:
return {
"query": """
query GetUsers($limit: Int!, $offset: Int!) {
users(limit: $limit, offset: $offset) {
id
name
email
}
}
""",
"variables": {
"limit": 10,
"offset": 0
}
}
With authorization¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.graphql(
url="https://api.example.com/graphql",
headers={"Authorization": "Bearer YOUR_TOKEN"}
)
async def get_profile(resp: Response) -> dict:
return {"query": "{ me { name email } }"}
Using with other methods¶
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
@app.get(url="https://httpbin.org/get")
async def http_get(resp: Response) -> dict:
return resp.json()
@app.graphql(url="https://api.example.com/graphql")
async def graphql_query(resp: Response) -> dict:
return {"query": "{ version }"}
# Run both requests
app.run()
# Run only GraphQL
app.run(tags=["graphql"])
With Pydantic Validation¶
from pydantic import BaseModel
from fasthttp import FastHTTP
from fasthttp.response import Response
app = FastHTTP()
class User(BaseModel):
id: int
name: str
email: str
@app.graphql(
url="https://api.example.com/graphql",
response_model=User
)
async def get_user(resp: Response) -> dict:
return {"query": "{ user(id: 1) { id name email } }"}
# For list of objects
@app.graphql(
url="https://api.example.com/graphql",
response_model=list[User]
)
async def get_users(resp: Response) -> dict:
return {"query": "{ users { id name email } }"}
With Dependencies¶
from fasthttp import FastHTTP, Depends
from fasthttp.response import Response
app = FastHTTP()
async def add_auth(route, config):
config.setdefault("headers", {})["Authorization"] = "Bearer my-token"
return config
async def add_trace_id(route, config):
import uuid
config.setdefault("headers", {})["X-Trace-ID"] = str(uuid.uuid4())
return config
@app.graphql(
url="https://api.example.com/graphql",
operation_type="mutation",
dependencies=[Depends(add_auth), Depends(add_trace_id)]
)
async def create_user(resp: Response) -> dict:
return {
"query": "mutation { createUser(name: $name) { id } }",
"variables": {"name": "John"}
}
With Both response_model and Dependencies¶
from pydantic import BaseModel
from fasthttp import FastHTTP, Depends
from fasthttp.response import Response
app = FastHTTP()
class User(BaseModel):
id: int
name: str
email: str
async def add_auth(route, config):
config.setdefault("headers", {})["Authorization"] = "Bearer my-token"
return config
@app.graphql(
url="https://api.example.com/graphql",
response_model=User,
dependencies=[Depends(add_auth)]
)
async def get_user(resp: Response) -> dict:
return {"query": "{ user(id: 1) { id name email } }"}
See also¶
- Middleware — for adding logic
- Configuration — settings
- Quick Start — basics