Skip to main content

IOTA GraphQL RPC

The GraphQL server provides read access to the Indexer database and enables transaction execution through the fullnode JSON-RPC API.

Architecture

The GraphQL server acts as a bridge between:
  • Indexer Database: For querying historical and indexed data
  • Fullnode JSON-RPC API: For transaction execution
┌─────────────┐
│   Clients   │
└──────┬──────┘


┌─────────────────┐
│  GraphQL Server │
└────┬────────┬───┘
     │        │
     ↓        ↓
┌────────┐ ┌─────────┐
│  Index │ │Fullnode │
│   DB   │ │JSON-RPC │
└────────┘ └─────────┘

Key Features

  • Built with async-graphql
  • Automatically generated schema from Rust types
  • Interactive GraphiQL IDE for exploring the API
  • Query and Mutation support

Query Type

Handles all data fetching operations:
  • Objects, owners, coins, events
  • Transaction blocks
  • Move packages
  • Checkpoints and protocol information
  • Dry run (simulation) of transactions

Mutation Type

Handles data modification:
  • Execute transaction blocks
  • Submit transactions to fullnode

GraphQL vs JSON-RPC Mapping

JSON-RPC APIGraphQL Equivalent
CoinApiQuery::coins, Query::coin_metadata
GovernanceApiQuery::epoch
MoveUtilsApiQuery::type_
ReadApiQuery::transaction_block, Query::objects, etc.
ExtendedApiQuery::epoch, Query::objects, Query::transaction_blocks
IndexerApiQuery::object, Object::events, etc.
WriteApiMutation::execute_transaction_block, Query::dry_run_transaction_block

Prerequisites

Before running the GraphQL server, you need:
  1. Running Indexer database (PostgreSQL)
  2. Fullnode (optional, for transaction execution)
    • Required only if you need transaction execution capabilities

Running the GraphQL Server

See pg-services-local which automatically sets up:
  • GraphQL server
  • Indexer instance
  • PostgreSQL database
  • Local network

Manual Setup

Basic Launch

Start the server with default configuration:
cargo run --bin iota-graphql-rpc start-server
The server will be available at: http://127.0.0.1:8000

Custom Configuration

Specify database URL, node RPC URL, and server address:
cargo run --bin iota-graphql-rpc start-server \
  --db-url "postgres://postgres:postgrespw@localhost/iota_indexer" \
  --node-rpc-url "http://localhost:9000" \
  --host "127.0.0.1" \
  --port 8000
Command-line Options:
  • --db-url: PostgreSQL database connection URL
  • --node-rpc-url: Fullnode RPC URL for transaction execution
  • --host: Server host address (default: 127.0.0.1)
  • --port: Server port (default: 8000)
  • --config: Path to TOML configuration file

Advanced Configuration

Use a TOML configuration file for fine-grained control:
[limits]
max-query-depth = 15
max-query-nodes = 500
max-output-nodes = 100000
max-query-payload-size = 5000
max-db-query-cost = 20000
default-page-size = 5
max-page-size = 10
request-timeout-ms = 15000
max-type-argument-depth = 16
max-type-argument-width = 32
max-type-nodes = 256
max-move-value-depth = 128

[background-tasks]
watermark-update-ms = 500
Load the config file:
cargo run --bin iota-graphql-rpc start-server --config config.toml
See ServiceConfig in config.rs for all available options.

Using GraphiQL IDE

Access the interactive GraphiQL IDE at: http://127.0.0.1:8000

Example Query

Test the server with this simple query:
# Returns the chain identifier for the chain that the server is tracking
{
  chainIdentifier
}

More Examples

Find additional query examples in the examples directory.

Running with Indexer

For local development, you may want to run both the Indexer (to populate data) and GraphQL server:

Using iota start Subcommand

From the repository root:
cargo run --features indexer --bin iota start \
  --with-indexer \
  --pg-port 5432 \
  --pg-db-name iota_indexer \
  --with-graphql=0.0.0.0:8000
This starts:
  • Local IOTA network
  • Indexer Sync worker
  • GraphQL server on 0.0.0.0:8000

Standalone Indexer

See Indexer standalone setup to run the Indexer separately.

Development Setup

For VS Code users, update .vscode/settings.json with the Diesel backend feature:
{
  "rust-analyzer.cargo.features": ["pg_backend"]
}

Running Tests

Prerequisites

Start a PostgreSQL test database:
# Follow Indexer database setup
# See: /services/indexer#database-setup

Run Server Tests

cargo nextest run -p iota-graphql-rpc \
  --features pg_integration \
  --no-fail-fast \
  --test-threads 1

Test GraphQL-JSON-RPC Compatibility

pnpm --filter @iota/graphql-transport test:e2e

Regenerating GraphQL Schema

After code changes, regenerate the schema:
cargo run --bin iota-graphql-rpc generate-schema
If snapshot tests fail:
# Run snapshot test
cargo nextest run -p iota-graphql-rpc -- test_schema_sdl_export

# Review and accept changes
cargo insta review

Environment Variables

The GraphQL server respects standard PostgreSQL environment variables:
  • PGHOST: Database host
  • PGPORT: Database port
  • PGUSER: Database user
  • PGPASSWORD: Database password
  • PGDATABASE: Database name

Connection Examples

Using cURL

curl -X POST http://127.0.0.1:8000 \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ chainIdentifier }"
  }'

Using JavaScript/TypeScript

import { GraphQLClient } from 'graphql-request';

const client = new GraphQLClient('http://127.0.0.1:8000');

const query = `
  {
    chainIdentifier
  }
`;

const data = await client.request(query);
console.log(data);

Using Python

import requests

url = 'http://127.0.0.1:8000'
query = '{ chainIdentifier }'

response = requests.post(url, json={'query': query})
print(response.json())

Build docs developers (and LLMs) love