GraphQL API
Torii's GraphQL API provides type-safe access to your indexed Dojo world data. The schema is dynamically generated from your world's models, offering both flexible queries and real-time subscriptions.
Quick Start
Start Torii and access the GraphQL endpoint:
torii --world <WORLD_ADDRESS>
- GraphQL API:
http://localhost:8080/graphql
- GraphiQL IDE:
http://localhost:8080/graphql
(in browser)
Core Features
- Dynamic Schema: Auto-generated from your world's model definitions
- Real-time Subscriptions: WebSocket-based live updates
- Flexible Pagination: Cursor-based and offset/limit support
- Type Safety: Fully typed with introspection support
Schema Structure
Torii generates two types of queries:
Generic Queries:entities
- Access all entities with flexible filteringmodels
- Retrieve model definitions and metadatatransactions
- Query indexed transaction data
{modelName}Models
- Custom queries for each registered model- Example:
positionModels
,movesModels
,playerModels
Model-specific queries provide optimized filtering, sorting, and type-safe field access.
Basic Queries
Model Metadata
Query model information using the model selector:
query {
model(id: "0x28b9a...") {
id
name
classHash
}
}
This query will return an output like this:
{
"data": {
"model": {
"id": "0x28b9a...",
"name": "Position",
"classHash": "0x2e9c4..."
}
}
}
Tip: Use stark-utils or
starkli
to compute model selectors.
Model Data
Query specific model data with automatic pagination:
query {
movesModels {
edges {
node {
player
remaining
last_direction
}
}
}
}
This query will return an output like this:
{
"data": {
"movesModels": {
"edges": [
{
"node": {
"player": "0xb3ff4...",
"remaining": 100,
"last_direction": "None"
}
}
]
}
}
}
Transactions
Query world transactions with pagination:
query {
transactions {
edges {
node {
id
transactionHash
senderAddress
}
}
totalCount
}
}
This query will return an output like this:
{
"data": {
"transactions": {
"edges": [
{
"node": {
"id": "0x00000...:0x4b264...",
"transactionHash": "0x4b264...",
"senderAddress": "0xb3ff4...",
"calldata": [
"0x1",
"0x7ec42...",
"0x217c7...",
"0x0"
]
}
},
# ... four more results
],
"totalCount": 5
}
}
}
Pagination
Torii supports both cursor-based and offset/limit pagination using GraphQL Connection types.
Cursor-Based Pagination
Recommended for performance. Use first
/after
for forward pagination, last
/before
for backward:
query {
entities(first: 10) {
edges {
cursor
node { id }
}
pageInfo {
hasNextPage
endCursor
}
}
}
This query will return an output like this, with two results out of five.
{
"entities": {
"totalCount": 5,
"edges": [
{
"cursor": "Y3Vyc29yX29uZQ==",
"node": {
"id": "0x54f58..."
}
},
{
"cursor": "Y3Vyc29yX3R3bw==",
"node": {
"id": "0x2c2ed..."
}
},
]
}
}
Next page, using the cursor from the previous query.
query {
entities(first: 3, after: "Y3Vyc29yX3R3bw==") {
# ... same fields
}
}
Offset/Limit Pagination
Simpler but less efficient for large datasets:
query {
entities(offset: 20, limit: 10) {
edges {
node { id }
}
totalCount
}
}
Real-time Subscriptions
Subscriptions provide WebSocket-based real-time updates when world state changes.
Model Registration
Listen for new model registrations:
subscription {
modelRegistered {
id
name
namespace
}
}
Entity Updates
Subscribe to specific entity changes:
subscription {
entityUpdated(id: "0x54f58...") {
id
updatedAt
models {
__typename
... on Position {
vec { x, y }
}
... on Moves {
remaining
}
}
}
}
Event Stream
Monitor all world events with filtering support:
subscription {
eventEmitted {
id
keys
data
transactionHash
}
}
GraphiQL IDE
Use the built-in GraphiQL IDE at http://localhost:8080/graphql
to:
- Explore Schema: Browse all available queries, mutations, and subscriptions
- Auto-completion: IntelliSense support for writing queries
- Real-time Testing: Test subscriptions with live data
- Documentation: Built-in schema documentation
Best Practices
Query Optimization:- Use model-specific queries instead of generic
entities
for better performance - Request only the fields you need
- Use cursor-based pagination for large datasets
- Subscribe to specific entities rather than all events when possible
- Handle connection drops and reconnection in production
- Use subscription filters to reduce bandwidth