Skip to main content

Using GraphQL fragments

GraphQL fragments allow you to define reusable field selections that can be shared across multiple queries. Instead of duplicating the same field selections in every query, define them once as a fragment and reference them with standard GraphQL spread syntax (...fragmentName).

This is particularly useful when multiple Transformations or Generators need to query the same fields from a model. Update the fragment once, and all queries that reference it pick up the change on their next execution.

Prerequisites

1. Define a fragment file

Create a .gql file containing one or more fragment definitions. Each fragment targets a specific GraphQL type and selects the fields you want to reuse.

Create a file named fragments/interface_fields.gql:

fragment interfaceFields on InfraInterfaceL3 {
name {
value
}
description {
value
}
speed {
value
}
ip_addresses {
edges {
node {
address {
value
}
}
}
}
}
info

The type after on must match a valid model in your Infrahub schema. In this example, InfraInterfaceL3 refers to the model kind as it appears in GraphQL queries.

2. Declare the fragment in .infrahub.yml

Add a graphql_fragments section to your .infrahub.yml file. Each entry requires a name and a file_path relative to the repository root.

graphql_fragments:
- name: interface_fields
file_path: "fragments/interface_fields.gql"

queries:
- name: device_interfaces_query
file_path: "queries/device_interfaces.gql"

The file_path field accepts either a single .gql file or a directory. When pointing to a directory, Infrahub loads all .gql files within it.

3. Reference fragments in a query

Use the standard GraphQL spread syntax (...fragmentName) to reference a fragment in any query file declared in the same repository.

Create a file named queries/device_interfaces.gql:

query DeviceInterfaces($device_name: String!) {
InfraDevice(name__value: $device_name) {
edges {
node {
name {
value
}
interfaces {
edges {
node {
...interfaceFields
}
}
}
}
}
}
}

When Infrahub imports this query from the repository, it detects the ...interfaceFields spread, resolves it against the declared fragment files, and stores the complete query with the fragment definition included inline.

4. Sync the repository

After committing the fragment file, the .infrahub.yml update, and the query file, sync the repository with Infrahub. Fragments are processed during the same repository sync that imports GraphQL queries.

If you are testing locally with infrahubctl, the fragment resolution happens automatically when rendering Transformations:

infrahubctl render device_config_transform device_name=router01

5. Verify the result

Open the GraphQL query in the Infrahub web interface or query it via the API. The stored query contains the fragment definition included inline alongside the operation, so it executes without any additional resolution at runtime.

curl -s "https://<host>/api/query/device_interfaces_query?device_name=router01" | python -m json.tool

Advanced usage

Multiple fragments per file

A single .gql file can contain multiple fragment definitions:

fragment interfaceFields on InfraInterfaceL3 {
name {
value
}
speed {
value
}
}

fragment addressFields on InfraIPAddress {
address {
value
}
prefix_length {
value
}
}

Both fragments become available to any query in the repository.

Directory-based declarations

Point file_path to a directory to load all .gql files within it:

graphql_fragments:
- name: all_fragments
file_path: "fragments/"

Infrahub loads all .gql files in the fragments/ directory in alphabetical order.

Transitive fragments

Fragments can reference other fragments. Infrahub resolves dependencies transitively and detects circular references.

fragment deviceDetails on InfraDevice {
name {
value
}
interfaces {
edges {
node {
...interfaceFields
}
}
}
}

When a query uses ...deviceDetails, Infrahub automatically includes both deviceDetails and interfaceFields in the resolved query.

Error handling

Infrahub validates fragments during repository sync and raises specific errors:

ErrorCause
FragmentFileNotFoundErrorThe file_path in .infrahub.yml does not exist in the repository
FragmentNotFoundErrorA query references a fragment name that is not defined in any declared fragment file
DuplicateFragmentErrorThe same fragment name is defined in multiple files
CircularFragmentErrorTwo or more fragments reference each other, creating a dependency cycle