Query the Hosted Service
Prerequisites
Install Rust and Cargo, the Rust package manager
Open your Terminal application then run the following command
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOverview
The Graph is a decentralized protocol that enables developers to query data from blockchains using GraphQL. In this lesson, we will use Rust to submit a GraphQL query to the graph-network-mainnet subgraph on The Graph’s Hosted Service. This hands-on lesson will provide you with the practical experience needed to interface with The Graph's ecosystem, and moreover, demonstrate the immense potential of leveraging Rust to interact with decentralized data networks. Let's dig in and uncover the incredible possibilities that await us in the realm of Rust, GraphQL, and The Graph's Hosted Service!
GraphQL query
To start, let's discuss the subgraph and GraphQL query we're submitting. The graph-network-mainnet subgraph extracts data from the protocol's smart contracts and makes it accessible via GraphQL queries. Indexers are the node operators of the protocol and allocate GRT tokens to subgraphs as part of their operations.
In this lesson, we're requesting data about indexers that is defined in the protocol's smart contracts. Our query is filtering results to the first 10 indexers who have allocated at least 1 GRT token to any subgraph in the protocol. Finally we're narrowing down the returned fields to id, defaultDisplayName, and stakedTokens.
Table 1. Subgraph field descriptions
id
the Ethereum address of the Indexer
defaultDisplayName
the current default display name of the Indexer. Potentially null and used to filter queries
stakedTokens
current tokens staked in The Graph protocol
Figure 1. Subgraph query
query indexers {
indexers(first:10, where: {allocatedTokens_gt: "0"}) {
id
defaultDisplayName
stakedTokens
}
}Getting started with Rust
Coming soon
Create a new cargo project
Open your Terminal application and change to your home directory
cd ~Create a new directory called
rohrand change into it
mkdir -p rohr && cd rohrCreate a new
cargoproject calledindexer_subgraph_query
cargo new indexer_subgraph_queryChange into the new
indexer_subgraph_querydirectory
cd indexer_subgraph_queryAdd dependencies to your project
Open
Cargo.tomlwithnano
nano Cargo.tomlserde = { version = "1.0.149", features = ["derive"] }
reqwest = { version = "0.11", features = ["json"]}
tokio = { version = "1.23.0", features = ["full"] }Save your changes to
Cargo.tomland exitnano
ctrl + x
yWrite Rust code
structs.rs
Create a new file called
structs.rsin thesrcdirectory
nano src/structs.rsAdd the following use declarations to
src/structs.rs
use std::string::String;
use serde::Deserialize;Next define a few
structstatements insrc/structs.rs
#[allow(non_snake_case)]
#[derive(Debug, Deserialize, PartialEq)]
pub struct Indexer {
pub id: String,
pub defaultDisplayName: Option<String>,
pub stakedTokens: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct IndexerData {
pub indexers: Vec<Indexer>
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct IndexerResponse {
pub data: IndexerData
}Notice that we created three structs:
IndexerResponse: the highest-level struct in the hierarchy. It defines the response format from thePOSTrequest sent to The Graph's Hosted ServiceIndexerDataandIndexer: nested structs which define data returned in theIndexerResponse
Each Indexer in The Graph protocol would theoretically be assigned to an Indexer struct, with the IndexerData struct containing all Indexer structs (or a subset based on the query filter submitted, i.e. first 10).
Finally, IndexerData is the value of the IndexerResponse data field.
Save your changes to
src/structs.rsand exitnano
ctrl + x
yYour file structs.rs will look something like this
use std::string::String;
use serde::Deserialize;
#[allow(non_snake_case)]
#[derive(Debug, Deserialize, PartialEq)]
pub struct Indexer {
pub id: String,
pub defaultDisplayName: Option<String>,
pub stakedTokens: Option<String>,
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct IndexerData {
pub indexers: Vec<Indexer>
}
#[derive(Debug, Deserialize, PartialEq)]
pub struct IndexerResponse {
pub data: IndexerData
}main.rs
Open
src/main.rswithnano
nano src/main.rsDelete all existing lines in the file
ctrl + shift + kAdd the following user declarations to the top of
src/main.rs
use std::collections::HashMap;
mod structs;
use crate::structs::*;Run your program
From your terminal, use cargo to compile and run your Rust program
cargo runLast updated