How to Interact with Fuel Core Using the GraphQL API: A Complete Developer's Guide
Fuel Core exposes a built-in GraphQL service that allows developers to query blockchain data, submit transactions, and subscribe to real-time block events via HTTP, configurable through ServiceConfig and accessible via the official FuelClient or raw HTTP requests.
The FuelLabs/fuel-core repository ships with a comprehensive GraphQL layer that serves as the primary interface for external applications to interact with the Fuel network. This service runs as an integrated sub-system within the node, providing both synchronous query capabilities and asynchronous subscriptions over Server-Sent Events.
GraphQL Service Architecture
The GraphQL implementation spans multiple modules under crates/fuel-core/src/graphql_api/, integrating configuration management, HTTP routing, and schema execution.
Configuration Layer
According to the source code in crates/fuel-core/src/graphql_api.rs (lines 21-49), the service is controlled by the Config and ServiceConfig structures. These hold the listener address, query complexity limits, depth restrictions, and cost settings. When initializing a node via Config::local_node(), GraphQL is enabled by default and binds to 127.0.0.1:4000, though you can customize cfg.graphql_config.addr to any valid socket address.
Service Construction and Routing
In crates/fuel-core/src/graphql_api/api_service.rs (lines 34-74), the new_service function constructs the GraphQL runner. It first builds a CoreSchema with extensions for metrics, validation, and block-height checks, then wires this schema into an Axum HTTP router. The router applies middleware for CORS, request timeouts, concurrency limits, and body-size restrictions before exposing the following endpoints:
/v1/graphql– Accepts POST requests with JSON-encoded GraphQL queries and mutations./v1/graphql-sub– Handles GraphQL subscriptions using Server-Sent Events for real-time data streaming./v1/playground– Serves the interactive GraphiQL IDE for schema exploration and manual testing./v1/healthand/v1/metrics– Expose node health status and operational telemetry.
Request handling is performed by dedicated functions defined in the same file: graphql_handler executes queries against the schema, graphql_subscription_handler manages streaming subscriptions, and health returns the node's operational status.
Starting a Node with GraphQL Enabled
To launch a Fuel Core node with the GraphQL service active, initialize the configuration using Config::local_node() and start the service via FuelService::from_database.
use fuel_core::{
service::{Config, FuelService},
database::Database,
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize default configuration with GraphQL enabled on port 4000
let mut cfg = Config::local_node();
cfg.graphql_config.addr = "127.0.0.1:4000".parse()?;
// Start the node and all sub-services including GraphQL
let service = FuelService::from_database(Database::default(), cfg).await?;
service.start().await?;
Ok(())
}
The Config::local_node() method populates ServiceConfig with sensible defaults for complexity limits and timeouts, which you can override directly on the cfg.graphql_config object before starting the service.
Querying Blockchain Data via HTTP
Once the node is running, you can execute GraphQL queries by sending POST requests to /v1/graphql with a JSON payload containing the query string.
curl -X POST http://127.0.0.1:4000/v1/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{ block(height: 0) { id header { height timestamp } } }"}'
The server returns a JSON response containing the requested data:
{
"data": {
"block": {
"id": "...",
"header": {
"height": "0",
"timestamp": "..."
}
}
}
}
Subscribing to Real-Time Events
For applications requiring live updates, the FuelClient Rust library abstracts the subscription protocol. The client posts GraphQL subscription queries to /v1/graphql-sub and yields Server-Sent Events as implemented in crates/fuel-core/src/graphql_api/api_service.rs.
use fuel_core_client::client::FuelClient;
use futures::StreamExt;
use std::time::Duration;
use tokio::time::timeout;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize client with URL fail-over support
let client = FuelClient::with_urls(&["http://127.0.0.1:4000/v1/graphql"])
.expect("client creation");
// Subscribe to new block events
let mut sub = client
.new_blocks_subscription()
.await
.expect("subscription");
// Await next block with timeout protection
let block = timeout(Duration::from_secs(5), sub.next())
.await??.expect("block event");
println!("New block at height {}", block.sealed_block.entity.header().height());
Ok(())
}
The new_blocks_subscription() method returns a stream that emits events whenever the chain produces a new block, handling the underlying HTTP upgrade and SSE parsing automatically.
Using the GraphiQL Playground
For interactive development and schema exploration, navigate to http://127.0.0.1:4000/v1/playground in your browser. This endpoint, generated by render_graphql_playground in api_service.rs, loads the GraphiQL IDE pre-configured with the node's schema documentation, allowing you to construct queries, test mutations, and verify subscription behavior without writing client code.
Key Implementation Files
| File | Purpose |
|---|---|
crates/fuel-core/src/graphql_api.rs |
Defines Config and ServiceConfig structures for service parameters. |
crates/fuel-core/src/graphql_api/api_service.rs |
Implements new_service, Axum routing, and request handlers (graphql_handler, graphql_subscription_handler). |
crates/fuel-core/src/schema/ |
Contains CoreSchema definitions for queries, mutations, and subscriptions. |
tests/tests/fuel_client.rs |
Integration tests demonstrating FuelClient usage, fail-over logic, and subscription handling. |
Summary
- Fuel Core exposes a GraphQL service via
Config::local_node()that binds to a configurable address (default127.0.0.1:4000). - The
new_servicefunction inapi_service.rsconstructs an Axum-based HTTP server mountingCoreSchemaat/v1/graphql(queries) and/v1/graphql-sub(subscriptions). - Developers can query data via standard HTTP POST requests or use the
FuelClientRust library for type-safe interactions and automatic fail-over. - Real-time subscriptions use Server-Sent Events streamed through the
/v1/graphql-subendpoint, accessible vianew_blocks_subscription()and similar methods. - The
/v1/playgroundendpoint provides an interactive GraphiQL interface for development and debugging.
Frequently Asked Questions
How do I change the GraphQL listener address and port?
Modify the addr field on cfg.graphql_config before starting the service, as shown in crates/fuel-core/src/graphql_api.rs (lines 21-49). The default configuration used by Config::local_node() binds to 127.0.0.1:4000, but you can parse any valid socket address string to customize the binding.
What is the difference between /v1/graphql and /v1/graphql-sub?
The /v1/graphql endpoint handles standard request-response queries and mutations via HTTP POST, while /v1/graphql-sub establishes long-lived connections using Server-Sent Events to stream subscription data such as new blocks or transaction status updates. The latter is handled by graphql_subscription_handler in api_service.rs.
Can I use GraphQL subscriptions from languages other than Rust?
Yes. While the fuel_core_client crate provides a convenient Rust wrapper, any HTTP client capable of consuming Server-Sent Events can connect to /v1/graphql-sub. Send a POST request with a subscription query, then parse the SSE stream for events formatted according to the GraphQL specification.
Where are query complexity and depth limits configured?
These limits reside in the ServiceConfig structure defined in crates/fuel-core/src/graphql_api.rs. You can adjust complexity thresholds, query depth limits, and execution timeouts directly on the graphql_config object before initializing FuelService::from_database to prevent resource exhaustion attacks.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →