GraphQL Module

The GraphQL module adds a fully-featured GraphQL API layer to your Vorte application with automatic schema generation from SQLAlchemy models, an interactive playground, WebSocket subscriptions, and structured resolver patterns.

Configuration

example.py
python
Copied!
1from vorte import Vorte
2
3app = Vorte(
4 auto_load=True,
5 config={
6 "graphql": {
7 "enabled": True,
8 "path": "/graphql",
9 "playground": True,
10 "auto_schema": True,
11 "introspection": True,
12 "subscriptions": {
13 "enabled": True,
14 "backend": "websocket",
15 "path": "/graphql/ws",
16 },
17 "depth_limit": 10,
18 "complexity_limit": 500,
19 },
20 },
21)

Auto-Schema Generation

When auto_schema is enabled, Vorte inspects your SQLAlchemy models and generates GraphQL types, queries, and mutations automatically.

base.py
python
Copied!
1from sqlalchemy import Column, Integer, String, DateTime, Boolean
2from sqlalchemy.orm import DeclarativeBase
3
4class Base(DeclarativeBase):
5 pass
6
7class User(Base):
8 __tablename__ = "users"
9 id = Column(Integer, primary_key=True)
10 name = Column(String(255))
11 email = Column(String(255), unique=True)
12 active = Column(Boolean, default=True)
13 created_at = Column(DateTime)
14
15class Post(Base):
16 __tablename__ = "posts"
17 id = Column(Integer, primary_key=True)
18 title = Column(String(500))
19 content = Column(String)
20 author_id = Column(Integer, ForeignKey("users.id"))
21 published = Column(Boolean, default=False)
22 created_at = Column(DateTime)
23
24# Auto-generated schema includes:
25# type User { id: Int!, name: String, email: String, active: Boolean, createdAt: DateTime, posts: [Post!] }
26# type Post { id: Int!, title: String, content: String, authorId: Int, published: Boolean, createdAt: DateTime, author: User }
27# type Query { users(limit: Int, offset: Int): [User!]!, user(id: Int!): User, posts(limit: Int, offset: Int): [Post!]! }
28# type Mutation { createUser(name: String!, email: String!): User!, updateUser(id: Int!, name: String): User!, deleteUser(id: Int!): Boolean! }

Custom Resolvers

resolve_users.py
python
Copied!
1from vorte.graphql import Resolver, resolver
2
3@resolver("Query", "users")
4async def resolve_users(
5 limit: int = 20,
6 offset: int = 0,
7 active_only: bool = True,
8):
9 query = select(User)
10 if active_only:
11 query = query.where(User.active == true())
12 query = query.limit(limit).offset(offset)
13 return await db.fetch_all(query)
14
15@resolver("Query", "user")
16async def resolve_user(user_id: int):
17 user = await db.fetch_one(
18 "SELECT * FROM users WHERE id = :id", {"id": user_id}
19 )
20 if not user:
21 raise GraphQLError(f"User {user_id} not found")
22 return user
23
24@resolver("Mutation", "createUser")
25async def resolve_create_user(name: str, email: str):
26 user = await db.execute(
27 "INSERT INTO users (name, email) VALUES (:name, :email) RETURNING *",
28 {"name": name, "email": email},
29 )
30 return user
31
32@resolver("User", "posts")
33async def resolve_user_posts(user: dict, limit: int = 10):
34 return await db.fetch_all(
35 "SELECT * FROM posts WHERE author_id = :aid LIMIT :limit",
36 {"aid": user["id"], "limit": limit},
37 )

Interactive Playground

The built-in GraphQL playground provides an interactive editor with schema exploration, query history, and real-time validation. Access it at the configured /graphql path in your browser.

example.py
python
Copied!
1# Enable playground in development
2app = Vorte(
3 auto_load=True,
4 config={
5 "graphql": {
6 "playground": True,
7 "introspection": True,
8 },
9 },
10)
11
12# Disable in production
13app = Vorte(
14 auto_load=True,
15 config={
16 "graphql": {
17 "playground": False,
18 "introspection": False,
19 },
20 },
21)

Subscriptions

Real-time data via WebSocket subscriptions. Clients receive updates when data changes without polling.

on_message.py
python
Copied!
1from vorte.graphql import Subscription, subscription
2
3@subscription("onMessage")
4async def on_message(room_id: str):
5 async for message in message_broker.subscribe(f"room:{room_id}"):
6 yield message
7
8@subscription("onUserStatus")
9async def on_user_status(user_id: int):
10 async for status in presence.track(user_id):
11 yield status

Client-side subscription example:

config.yaml
yaml
Copied!
1# WebSocket connection to ws://localhost:8000/graphql/ws
2# Subscription query:
3subscription OnMessage($roomId: String!) {
4 onMessage(roomId: $roomId) {
5 id
6 content
7 author {
8 name
9 }
10 createdAt
11 }
12}

Custom Scalar Types

datetimescalar.py
python
Copied!
1from vorte.graphql import Scalar
2
3@scalar(name="DateTime")
4class DateTimeScalar(Scalar):
5 @staticmethod
6 def serialize(value):
7 return value.isoformat()
8
9 @staticmethod
10 def parse_value(value):
11 return datetime.fromisoformat(value)
12
13 @staticmethod
14 def parse_literal(ast):
15 return datetime.fromisoformat(ast.value)
16
17@scalar(name="JSON")
18class JSONScalar(Scalar):
19 @staticmethod
20 def serialize(value):
21 return value
22
23 @staticmethod
24 def parse_value(value):
25 return value

Query Complexity and Depth Limits

example.py
python
Copied!
1app = Vorte(
2 auto_load=True,
3 config={
4 "graphql": {
5 "depth_limit": 10,
6 "complexity_limit": 500,
7 "rate_limit": {
8 "points": 100,
9 "duration": 60,
10 },
11 },
12 },
13)
Stay in the loop

Get Vorte release notes, module guides, and developer deep-dives. No spam — unsubscribe anytime.