Gql Functions

Gql Functions are automatically generated and imported based on the GraphQL operations in the project.

Example

example.gql
query GetUsers {
  users {
    id
    name
  }
}

mutation LoginUser($email: String!, $password: String!) {
  login(email: $email, password: $password) {
    id
    name
  }
}

The GraphQL document above will generate two Gql Functions (GqlGetUsers and GqlLoginUser) that are automatically imported, and can be utilized as shown below:

async function loadUsers() {
  const result = await GqlGetUsers()
}

async function handleLogin(email: string, password: string) {
  const result = await GqlLoginUser(email, password)
}

Understanding

Writing GraphQL operations in SFC components is not supported, this decision is at the heart of this module.

Naming Convention

Gql Functions are named based on their GraphQL operation name. The operation name is prefixed with Gql.

It is recommended to uniquely name your GraphQL operations to avoid naming conflicts.

example.gql
query GetComments {
  comments {
    id
  }
}

mutation CreateComment ($input: CommentInput!) {
  createComment(input: $input) {
    id
  }
}

The GraphQL document above contains two (2) operations, GetComments and CreateComment. The Gql Functions generated from these operations are GqlGetComments() and GqlCreateComment() respectively.

GraphQL Operations

GraphQL operations must be written in .gql / .graphql documents, and can be placed anywhere in the project. These documents are scanned and parsed to generate the necessary types and Gql Functions based on your GraphQL operations.

Grouping Operations

It is recommended to group related operations in a single file for better organization as seen in the example below.

queries/user.gql
query GetUser($id: String!) {
  user(id: $id) {
    id
    name
    email
  }
}

query GetUsers {
  users {
    id
    name
    email
  }
}

mutation CreateUser($input: UserInput!) {
  createUser(input: $input) {
    id
    name
    email
  }
}

Multiple Client Mode

In Multiple Client Mode GraphQL documents must be manually associated with their respective client.

This is done by either:

  • Naming the file with the special <clientname>.gql|graphql extension. This method takes precedence.
/nuxt-app/queries/demo.spacex.gql
  • Placing the document in a folder with the same name as the client.
/nuxt-app/queries/spacex/demo.gql

All GraphQL operations in this file will be associated with the spacex client.

GraphQL documents which don't match any of the aforementioned conventions are associated with the default client

Limitations

Understanding the current drawbacks of Gql Functions is important to avoid common pitfalls.

Chaining operations (Nuxt Context)

Gql Functions are not chainable. This is due to a current limitation of Vue 3 and inherently Nuxt 3, The context is lost during SSR after the first await statement, hence subsequent calls which rely on the nuxt instance context will fail.

The only exception here is when called directly within a plugin or the top level script setup.

Invalid approach
// This will not work
export const useExample = async () => {
  const { user } = await GqlUser()

  /* 
    nuxt instance has been lost
  */

  const myState = useState('example')

  const { relations } = await GqlRelations({ id: user.id })
}

The solution here is to leverage the useGql composable that Gql Functions are built on to maintain a single instance, and access any internal nuxt composables before the first await statement.

Recommended approach
export const useExample = async () => {
  // create an instance to make multiple queries / mutations
  const GqlInstance = useGql()

  // access `useState` before the first `await` statement
  const myState = useState('example')

  const { user } = await GqlInstance('user')

  const { relations } = await GqlInstance('relations', { id: user.id })

  // myState can be utilized
}
Gql Functions, as well as internal Nuxt 3 composables such as (useState, useRoute, useCookie, etc) are reliant on the nuxt context.

The nuxt instance is lost after the first await statement, hence, calling any function that is reliant on the nuxt context will result in the nuxt instance unavailable error.

Requires operation name

Gql Functions are only generated for operations that have a name.

queries/posts.gql
# bad practice
query {
  posts {
    id
    title
  }
}

# recommended
query GetPosts {
  posts {
    id
    title
  }
}
Anonymous operations are skipped and inaccesible to your application.