Skip to content
Graffle is a work in progress. Learn more.

Sending

Read Static First

This guide builds on Static. Read that first to understand document building - this guide focuses on how to send documents with a client instance.

Overview

Once you have a Graffle client instance, the client.gql() method sends GraphQL documents. This is the instance API - it requires a configured client.

What it accepts:

  • All the same inputs as the static builder (strings, objects)
  • Pre-built documents from the static builder
  • Legacy types like DocumentNode (from graphql package)

What it returns:

  • A Document Sender - an object with typed methods for executing operations
ts
import { Graffle } from 'graffle'

const client = Graffle.create().transport({
  url: 'https://api.example.com/graphql',
})

// Send a GraphQL string
const sender = client.gql(`
  query getPokemon($name: String!) {
    pokemonByName(name: $name) { name hp }
  }
`)

// Execute using the operation name
const pokemon = await sender.getPokemon({ name: 'Pikachu' })

What Can Be Sent

The client.gql() method accepts the same inputs as the static builder, plus pre-built documents and legacy types:

ts
const sender = client.gql(`query { pokemons { name } }`)
await sender.$send()

Sender Interface

When you call client.gql(), you get back a Document Sender with two ways to execute operations:

Operation Methods

Each named operation in your document becomes a typed method:

ts
const sender = client.gql(`
  query getPokemon($name: String!) {
    pokemonByName(name: $name) { name hp }
  }
  query getPokemons {
    pokemons { name }
  }
`)

const pokemon = await sender.getPokemon({ name: 'Pikachu' })
const pokemons = await sender.getPokemons()

How variables work:

  • Required variables - Must be provided: .getPokemon({ name: 'Pikachu' })
  • Optional variables - Can be omitted: .getPokemons() or .getPokemons({ filter: { type: 'FIRE' } })
  • No variables - Call with no arguments: .getPokemons()

TypeScript enforces this automatically based on your document.

Static Send Method

For runtime flexibility, use .$send():

ts
await client.gql('query getPokemons { pokemons { name } }').$send()
await client.gql(
  'query getPokemon($name: String!) { pokemonByName(name: $name) { hp } }',
).$send(
  { name: 'Pikachu' },
)

const sender = client.gql(`
  query getPokemon($name: String!) { pokemonByName(name: $name) { name hp } }
  query getPokemons { pokemons { name } }
`)
await sender.$send('getPokemon', { name: 'Pikachu' })
await sender.$send('getPokemons')

Variables

The relationship between operation names and variables:

ts
const sender = client.gql(`
  query pokemonDetails($name: String!, $includeStats: Boolean = false) {
    pokemonByName(name: $name) {
      name
      hp @include(if: $includeStats)
      attack @include(if: $includeStats)
    }
  }
`)

await sender.pokemonDetails({
  name: 'Pikachu',
  includeStats: true,
})

Anonymous operations (without names) only support .$send():

ts
const sender = client.gql(`query { pokemons { name } }`)
await sender.$send()

Released under the MIT License.