Quickstart¶
This guide will walk you through spinning up a full FastAPI GraphQL server over a PostgreSQL, SQLite, or MySQL database in just a few minutes.
1. Installation¶
Install the Gateway along with fastapi and an ASGI server:
pip install "db-graphql-gateway[fastapi]" uvicorn
uv add "db-graphql-gateway[fastapi]" uvicorn
2. Server Example¶
Here is a complete, production-ready example that connects to your database, introspects it, builds the GraphQL schema, and mounts it in FastAPI.
from contextlib import asynccontextmanager
from fastapi import FastAPI
import uvicorn
from db_graphql_gateway.database.adapters.postgres.adapter import PostgresAdapter
from db_graphql_gateway.schema.config import GatewayConfig
from db_graphql_gateway.schema.ir.builder import IRBuilder
from db_graphql_gateway.graphql.builder import GraphQLSchemaBuilder
from db_graphql_gateway.integrations.fastapi_integration import make_graphql_router
adapter = PostgresAdapter(dsn="postgresql://user:password@localhost:5432/my_db")
@asynccontextmanager
async def lifespan(app: FastAPI):
await adapter.connect()
inspector = adapter.inspector()
db_schema = await inspector.discover_schema()
ir = IRBuilder(type_mapper=adapter.type_mapper()).build(
db_schema=db_schema, config=GatewayConfig()
)
schema = GraphQLSchemaBuilder(db_adapter=adapter).build(
ir_types=ir, db_schema=db_schema
)
app.include_router(make_graphql_router(schema))
yield
await adapter.close()
app = FastAPI(title="My GraphQL API", lifespan=lifespan)
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000)
from contextlib import asynccontextmanager
from fastapi import FastAPI
import uvicorn
from db_graphql_gateway.database.adapters.sqlite.adapter import SQLiteAdapter
from db_graphql_gateway.schema.config import GatewayConfig
from db_graphql_gateway.schema.ir.builder import IRBuilder
from db_graphql_gateway.graphql.builder import GraphQLSchemaBuilder
from db_graphql_gateway.integrations.fastapi_integration import make_graphql_router
adapter = SQLiteAdapter(path="my_database.sqlite")
@asynccontextmanager
async def lifespan(app: FastAPI):
await adapter.connect()
inspector = adapter.inspector()
db_schema = await inspector.discover_schema()
ir = IRBuilder(type_mapper=adapter.type_mapper()).build(
db_schema=db_schema, config=GatewayConfig()
)
schema = GraphQLSchemaBuilder(db_adapter=adapter).build(
ir_types=ir, db_schema=db_schema
)
app.include_router(make_graphql_router(schema))
yield
await adapter.close()
app = FastAPI(title="My GraphQL API", lifespan=lifespan)
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000)
3. Schema Configuration (sgql.yaml)¶
Place a sgql.yaml alongside your server to customize the schema without code changes:
models:
- name: users
fields:
- name: email
is_sensitive: true # hidden from the GraphQL schema
auth:
providers:
- type: jwt
issuer: "https://my-auth-server.com"
audience: "my-api"
secret: "your-hs256-secret" # or use 'public_key' for RS256
algorithm: "HS256"
rules:
- target: posts
predicate: "{user_id} = {jwt.user_id}" # row-level policy
- target: comments
predicate: "{user_id} = {jwt.user_id}"
security:
max_depth: 8
max_aliases: 15
max_complexity: 100
Load it at startup:
import yaml
from db_graphql_gateway.schema.config import GatewayConfig
with open("sgql.yaml") as f:
config = GatewayConfig(**yaml.safe_load(f))
4. Authentication¶
JWT (built-in)¶
The gateway ships with a JWTAuthenticationProvider for HS256 and RS256 tokens:
from db_graphql_gateway.auth.jwt_provider import JWTAuthenticationProvider
from db_graphql_gateway.integrations.fastapi_integration import make_graphql_router
auth_provider = JWTAuthenticationProvider(
secret_or_key="your-secret",
algorithms=["HS256"],
issuer="https://my-auth-server.com",
audience="my-api",
)
router = make_graphql_router(schema, auth_provider=auth_provider)
OIDC / OAuth2 (via FastAPI dependencies)¶
For OIDC or any custom auth flow, pass a context_getter directly — the gateway forwards all **kwargs to Strawberry's GraphQLRouter:
from fastapi import Depends, Request
from fastapi.security import OAuth2PasswordBearer
from db_graphql_gateway.integrations.fastapi_integration import make_graphql_router
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def my_oidc_context(
request: Request,
token: str = Depends(oauth2_scheme),
) -> dict:
# Validate token with your OIDC provider here
user = await verify_oidc_token(token)
return {"request": request, "user": user}
router = make_graphql_router(schema, context_getter=my_oidc_context)
Any FastAPI dependency works
Because make_graphql_router passes **kwargs to strawberry.fastapi.GraphQLRouter, any FastAPI dependency injection pattern — including HTTPBearer, OpenIdConnect, or a custom class — works exactly as you'd expect.
5. Explore the API¶
Start your server:
uvicorn main:app --reload
Open your browser and navigate to the built-in GraphiQL IDE:
Example: Nested Query with Pagination¶
Thanks to the built-in DataLoader, you can immediately execute deeply nested queries. The gateway guarantees exactly one SQL query per relationship depth level — not one per row.
query GetUsersWithPosts {
users_connection(first: 10) {
edges {
node {
id
username
posts {
id
title
comments {
id
body
}
}
}
}
}
}
-- Depth 1: fetch users
SELECT * FROM users LIMIT 10;
-- Depth 2: fetch ALL posts for those users in ONE batched query
SELECT * FROM posts WHERE user_id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
-- Depth 3: fetch ALL comments for those posts in ONE batched query
SELECT * FROM comments WHERE post_id IN (101, 102, 103, ...);
6. The CLI (sgql)¶
Use the built-in CLI for diagnostics and CI tasks:
# Verify DB connection and introspect schema
sgql doctor --dsn postgresql://user:pass@localhost:5432/db
# Audit your schema config for security issues
sgql security --config sgql.yaml
# Validate sgql.yaml structure
sgql validate --config sgql.yaml