> ## Documentation Index
> Fetch the complete documentation index at: https://adro.codes/llms.txt
> Use this file to discover all available pages before exploring further.

# Defining Queries

Once you've defined several fragments, you can start defining your queries.

## Query definition.

```ts theme={null}
import { collectFragments } from "@adrocodes/pigeon";
import { HeroBannerFragment } from "@modules/hero-banner/hero-banner.pigeon";
import { z } from "zod";

const query = `
  ${collectFragments([HeroBannerFragment])}

  query GetPageData {
    page {
      heroBanner {
        ...${HeroBannerFragment.fragmentName}
      }
    }
  }
`
```

<Info>Nothing is stopping you from using `createDependency` for the `page` above. In the example above, the more dependencies you have, the more items you'll need to add to `collectFragments`. Abstracting `page` into a `createDependency` means you'll only need to update the `dependencies` key and the fragments will automatically be collected.</Info>

### What does `collectFragments` do?

`collectFragments` is a helper function that will collect all the fragments required for a query. This ensures that only the fragments you need are included and de-duped.

This will produce a string that looks like this:

```graphql theme={null}
fragment HeroBannerFragment on HeroBanner {
  title
  description
  image {
    ...ImageFragment
  }
}

fragment ImageFragment on Asset {
  url
  alt
  size { width height }
}
```

Notice how you didn't have to include `ImageFragment` in the `collectFragment` method, while traversing the `HeroBannerFragment` it found that `ImageFragment` was a dependency and included it.

## Query Schema.

```ts theme={null}
const schema = z.object({
  page: z.object({
    heroBanner: HeroBannerFragment.schema
  })
})
```

## Query Execution.

```ts theme={null}
const { data, error } = await client.query({ query })

const parsed = await schema.parseAsync(data)

return parsed
```

<Info>Be better than me and handle your errors, please.</Info>

Pigeon isn't opinionate on how you fetch the data so replace `client` with your GraphQL client of choice. Some clients may require the `query` method to be wrapped in a `gql` call, so be sure to check the documentation for your client.

Once you get your data back, you'll need to parse your data with the schema you defined. This will validate the data and transform it into the shape you need. I am using the `parseAsync` method to handle any `async` transforms however, if you don't have any `async` transforms you can use the `parse` method.

At this point, you can be confident that the data you are working with is valid and in the shape you need. If your data is invalid, zod will provide error details that you can debug further.
