> ## 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 Fragments

## What is a Fragment?

In the context of GraphQL, a fragment is a reusable piece of a GraphQL query. It allows you to define the shape of data that you want to work with. This is useful when you have multiple queries that need the same shape of data.

In the context of Pigeon, a fragment is defined with either the `createRegistration` or `createDependency` functions. It allows you to define the GraphQL fragment, zod schema and any dependencies it requires.

## What is the difference between `createRegistration` and `createDependency`?

They are identical except for 1 difference. `createRegistration` **requires** your schema to include a `__typename` field.

## What does a fragment need.

1. `__typename` - this is the GraphQL type name. GraphQL endpoints usually provide a explorer, which will show you the type name.
2. `fragmentName` - (**optional**) by default `Fragment` will be appended to the `__typename`. However, you can override this if required, a few examples of when it is needed will be listed below.
3. `fragment` - this is the GraphQL fragment, but only the "body" of the fragment. You **don't** have to include the `fragment on ...` portion of the fragment.
4. `schema` - this is the zod schema that will be used to validate the incoming data. Here you can perform any transformations. Remember `zod` transforms can be `async` so if you needed to fetch anything based on validated data, you can do that here.
5. `dependencies` - (**optional**) this is an array of other pigeon fragments that your fragment depends on. We'll use this to collect all the fragments required for a query, ensuring on what you need is included and de-duped.

## Demo.

We'll go through a simple example for defining a Hero Banner fragment. It'll be made up of 3 things, a `title`, `description` and `image`.

### Image Fragment.

We know that the `image` will be a consistent shape and something we'll reuse across the application. So we'll define a `createDependency` for the `image` fragment.

```ts theme={null}
import { createDependency } from "@adrocodes/pigeon";
import { z } from "zod";

export const ImageFragment = createDependency({
  __typename: "Asset",
  fragmentName: "ImageFragment",
  fragment: `
    url
    alt
    size { width height }
  `,
  schema: z.object({
    url: z.string().url().min(1),
    alt: z.string().min(1),
    size: z.object({
      width: z.number().positive(),
      height: z.number().positive(),
    }),
  }).transform(({ ...value, size }) => ({
    ...value,
    ...size
  }))
})
```

Our fictional GraphQL endpoint only has 1 `__typename` for all asset data. So we've defined the `__typename` as `Asset`. We've also defined a `fragmentName` as `ImageFragment` as we might define another fragment for videos, not specifying a `fragmentName` would cause a conflict.

<Info>**Important:** If you define multiple fragments for 1 typename it is a good idea to define the `fragmentName` manually to avoid conflicts.</Info>

We are also using the `transform` method to merge the `size` object into the parent object. This is a simple example of how you can transform data.

### Hero Banner Fragment.

```ts theme={null}
import { createRegistration } from "@adrocodes/pigeon";
import { z } from "zod";
import { ImageFragment } from "@modules/image/image.pigeon";

export const HeroBannerFragment = createRegistration({
  __typename: "HeroBanner",
  fragment: `
    title
    description
    image {
      ...${ImageFragment.fragmentName}
    }
  `,
  schema: z.object({
    __typename: z.literal("HeroBanner"),
    title: z.string().min(1),
    description: z.string().nullish(),
    image: ImageFragment.schema,
  }),
  dependencies: [ImageFragment]
})
```

Here is an example of the `createRegistration`, when to use `createRegistration` and `createDependency` really just depends if you need to include a `__typename` in your schema. For example, if you are pulling in a list of components and need to render components based on the `__typename` you would use `createRegistration`.

We are also using the `ImageFragment` we defined earlier as a dependency.

* In the `fragment` we are using the `...${ImageFragment.fragmentName}` syntax. In our case, this will turn into `...ImageFragment`.
* In the `schema` we are using the `ImageFragment.schema` to validate & transform the `image` field data.
* In the `dependencies` we are including the `ImageFragment` so that when we collect all the fragments required for a query, we include the `ImageFragment`.

<Note>Very important to use `fragmentName` within the `fragment` field, using `ImageFragment.fragment` will inject the actual fragment into the query, and can cause a error about defining a fragment but not using it.</Note>

If your UI component required different props to what the schema defines, for example, key names are different. You can use the `transform` method to transform the data into what your UI component needs. This avoids needing to change the UI component and/or requiring the frontend to add transformation logic to components.
