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

Requests

The gql method allows you to work directly with GraphQL syntax. It approximates what graphql-request was before it turned into graffle. Its name is also strategically chosen to leverage automatic GraphQL syntax highlighting that editors generally provide.

Sending Pre-Built Documents

The send method provides a one-shot API for executing pre-built GraphQL documents without chaining from .gql(). This is useful when working with:

  • Static builders from generated code (Graffle.document(), Graffle.query(), etc.)
  • Typed documents from codegen tools (GraphQL Code Generator, etc.)
  • Plain GraphQL strings
ts
import { Graffle } from './graffle/__.js'

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

// From static builder
const doc = Graffle.document({
  query: { getUser: { user: { id: true, name: true } } },
})
const result = await client.send(doc, { id: '123' })

// From codegen
import { GetUserDocument } from './graphql/generated.js'
const result = await client.send(GetUserDocument, { id: '123' })

// Plain string
const result = await client.send(`{ user { id name } }`)

Single vs Multiple Operations

For documents with a single operation, the operation name is optional:

ts
const doc = Graffle.document({
  query: { getUser: { user: { id: true } } },
})
await client.send(doc, { id: '123' }) // Operation name inferred

For documents with multiple operations, specify which operation to execute:

ts
const doc = Graffle.document({
  query: {
    getUser: { user: { id: true } },
    getPosts: { posts: { title: true } },
  },
})
await client.send(doc, 'getUser', { id: '123' })
await client.send(doc, 'getPosts')

Comparison with .gql()

ts
// Chained API - builds document inline
const result = await client.gql(doc).send({ id: '123' })

// One-shot API - uses pre-built document
const result = await client.send(doc, { id: '123' })

Sending Document Nodes

Graffle allows you to send DocumentNode instances (created from a class in the graphql package) directly.

Example
Gql Document Node
ts

import { 
Graffle
} from 'graffle'
import {
OpenTelemetry
} from 'graffle/extensions/opentelemetry'
import {
Throws
} from 'graffle/extensions/throws'
import {
parse
} from 'graphql'
const
graffle
=
Graffle
.
create
()
.
transport
({
url
: `http://localhost:3000/graphql`,
}) .
use
(
Throws
)
.
use
(
OpenTelemetry
())
const
data
= await
graffle
.
gql
(
parse
(`
query pokemonByName ($name: String!) { pokemonByName (name: $name) { name trainer { name } } } `)).
send
({
name
: `Pikachu` })
console.log(
data
)
txt
{
  pokemonByName: [ { name: 'Pikachu', trainer: { name: 'Ash' } } ]
}

You can attain type safety by creating your document with type variables. In a typical real project this would be something that a tool like GraphQL Code Generator automatically does for you.

Example
Gql Document Node Typed
ts

import { 
Graffle
} from 'graffle'
import {
parse
, type
TypedQueryDocumentNode
} from 'graphql'
const
graffle
=
Graffle
.
create
()
.
transport
({
url
: `http://localhost:3000/graphql`,
}) type
Document
=
TypedQueryDocumentNode
<
{
pokemonByName
: {
id
: string
name
: string
hp
: number
attack
: number
defense
: number
trainer
: {
name
: string }
} }, {
name
: string }
> const
document
=
parse
(`
query ($name: String!) { pokemonByName (name: $name) { name hp attack defense trainer { name } } } `) as
Document
const
data
= await
graffle
.
gql
(
document
).
send
({
name
: `Pikachu` })
console.log(
data
?.
pokemonByName
)
txt
[
  {
    name: 'Pikachu',
    hp: 35,
    attack: 55,
    defense: 40,
    trainer: { name: 'Ash' }
  }
]

Sending Strings

You can skip creating document nodes if you don't need them, instead just sending a string directly.

Example
Gql String
ts

import { 
Graffle
} from 'graffle'
const
graffle
=
Graffle
.
create
().
transport
({
url
: `http://localhost:3000/graphql` })
const
data
= await
graffle
.
gql
`
{ pokemons { name } } `.
send
()
console.log(
data
)
txt
{
  pokemons: [
    { name: 'Pikachu' },
    { name: 'Charizard' },
    { name: 'Squirtle' },
    { name: 'Bulbasaur' },
    { name: 'Caterpie' },
    { name: 'Weedle' },
    { name: 'Mew' }
  ]
}

You can still attain type safety even for the string input by casting your string to TypedDocumentString.

Example
Gql String Typed
ts

import { 
Graffle
, type
TypedDocument
} from 'graffle'
const
graffle
=
Graffle
.
create
().
transport
({
url
: `http://localhost:3000/graphql` })
/** * @remarks Typically this type would come from your code generation tool. * * @see https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#documentmode * @see https://github.com/graffle-js/graffle/issues/997 */ type
Document
=
TypedDocument
.
String
<
{
pokemonByName
: {
id
: string
name
: string
hp
: number
attack
: number
defense
: number
trainer
: {
name
: string
} } }, {
name
: string }
> const
data
= await
graffle
.
gql
<
Document
>`
query pokemonByName ($name: String!) { pokemonByName (name: $name) { name hp attack defense trainer { name } } } `.
send
({
name
: `Pikachu` })
console.log(
data
?.
pokemonByName
)
txt
[
  {
    name: 'Pikachu',
    hp: 35,
    attack: 55,
    defense: 40,
    trainer: { name: 'Ash' }
  }
]

Released under the MIT License.