Expand description
Compile-time validated macros for the Sui GraphQL API.
Two macros, both validated against the embedded Sui GraphQL schema:
Response— derive macro for response types. Generates JSON deserialization from declarative field paths, catching unknown fields and type mismatches before your code runs.graphql_query!— function-style macro for query/mutation strings. Validates the source against the schema, so unknown fields, undefined variables, and bad arguments fail to compile.
For a complete client that uses both, see
sui-graphql.
§Quick Start
use sui_graphql_macros::Response;
#[derive(Response)]
struct ObjectData {
#[field(path = "object.address")]
address: String,
#[field(path = "object.version")]
version: u64,
}
fn main() {}The macro validates that object.address and object.version exist in the schema
and that their types match at compile time. It then generates a
from_value(serde_json::Value) -> Result<Self, String> method, a borrowed
extract(&serde_json::Value) -> Result<Self, String> variant, and a Deserialize
implementation, so the struct can be used directly with
serde_json::from_value or as a response type in GraphQL client calls.
§Path Syntax
Paths use dot-separated segments with optional suffixes:
| Syntax | Meaning | Rust Type |
|---|---|---|
field | Required field | T |
field? | Nullable field | Option<T> |
field[] | Required list | Vec<T> |
field?[] | Nullable list | Option<Vec<T>> |
field[]? | List with nullable elements | Vec<Option<T>> |
field?[]? | Nullable list, nullable elements | Option<Vec<Option<T>>> |
Multiple ? markers between [] boundaries share one Option wrapper.
Each ? controls null tolerance at that specific segment.
The macro enforces that path suffixes match the Rust type at compile time.
For example, field? requires Option<T>, and field[] requires Vec<T>.
A mismatch (e.g., field? with String or field with Option<String>)
produces a compile error.
§Null Handling
use sui_graphql_macros::Response;
#[derive(Response)]
struct Example {
// null at `object` → error, null at `address` → error
#[field(path = "object.address")]
strict: String,
// null at `object` → Ok(None), null at `address` → Ok(None)
#[field(path = "object?.address?")]
flexible: Option<String>,
// null at `object` → Ok(None), null at `address` → error
#[field(path = "object?.address")]
partial: Option<String>,
}
fn main() {}§Lists
Use [] to mark list fields. The macro validates this matches the schema.
use sui_graphql_macros::Response;
#[derive(Response)]
struct CheckpointDigests {
#[field(path = "checkpoints.nodes[].digest")]
digests: Vec<String>,
// Nullable list with nullable elements
#[field(path = "checkpoints?.nodes?[]?.digest?")]
maybe_digests: Option<Vec<Option<String>>>,
}
fn main() {}§Aliases
Use alias:field when your GraphQL query uses aliases. The alias (before :) is the
JSON key used for extraction, while the field name (after :) is validated against
the schema. The alias itself is not schema-validated since it is user-defined in the
query.
use sui_graphql_macros::Response;
#[derive(Response)]
struct EpochCheckpoints {
// GraphQL alias "firstCp" maps to schema field "checkpoints"
#[field(path = "epoch.firstCp:checkpoints.nodes[].sequenceNumber")]
first_checkpoints: Vec<u64>,
}
fn main() {}§Flattened Responses
Use #[field(flatten)] to populate a field by passing the complete response value to
that field type’s borrowed extract method. This allows response types that read from
the same root value to be composed without cloning it or repeating their field paths.
flatten cannot be combined with path.
use sui_graphql_macros::Response;
#[derive(Response)]
struct ChainInfo {
#[field(path = "chainIdentifier")]
chain_id: String,
}
#[derive(Response)]
struct ResponseData {
#[field(flatten)]
chain: ChainInfo,
}
fn main() {}§Enums (GraphQL Unions)
Use #[response(root_type = "UnionType")] on enums with newtype variants:
#[derive(Response)]
#[response(root_type = "DynamicFieldValue")]
enum FieldValue {
#[response(on = "MoveValue")]
Value(MoveValueData),
MoveObject(MoveObjectData), // `on` defaults to variant name
}The macro dispatches on __typename in the JSON response.
§Attributes
| Attribute | Level | Description |
|---|---|---|
#[response(root_type = "Type")] | struct/enum | Schema type to validate against (default: "Query") |
#[response(schema = "path")] | struct/enum | Custom schema file (relative to CARGO_MANIFEST_DIR) |
#[field(path = "...")] | field | Dot-separated path with optional ?/[]/alias |
#[field(flatten)] | field | Populate by calling the field type’s extract with the complete response value |
#[field(skip_schema_validation)] | field | Skip compile-time schema checks for this field |
#[response(on = "TypeName")] | variant | GraphQL __typename to match (default: variant name) |
Macros§
- graphql_
query - Validate a GraphQL query or mutation against the embedded Sui schema at
compile time and return it as a
&'static str.
Derive Macros§
- Response
- Derive macro for GraphQL response types with nested field extraction.