HomeDev guideAPI ReferenceGraphQL
Dev guideUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Recursive directive

Describe the reason to have recursive directive and how to use it

The @recursive directive in GraphQL is a powerful tool designed to streamline and simplify queries that involve recursive or deeply nested structures. This directive aims to condense complex queries into more concise and readable forms, enhancing the clarity and manageability of the GraphQL schema.

Consider the following scenario where a lengthy and repetitive query is required to traverse a deeply nested structure:

query MyQuery {
  Content(locale: [en, sv]) {
    items {
      Created
      __typename
      Name
      ContentLink {
        ...ContentLinkFields
      }
    }
  }
}

fragment ContentLinkFields on ContentModelReference {
  Id
  WorkId
  GuidValue
  ProviderName
  Url
  Language {
    Link
    DisplayName
    Name
  }
  Expanded {
    ...ExpandedFields
    ContentLink {
      __typename
      Id
      WorkId
      GuidValue
      ProviderName
      Url
      Language {
        Link
        DisplayName
        Name
      }
      Expanded {
        ...ExpandedFields
        ContentLink {
          __typename
          Id
          WorkId
          GuidValue
          ProviderName
          Url
          Language {
            Link
            DisplayName
            Name
          }
          Expanded {
            ...ExpandedFields
            ContentLink {
              __typename
              Id
              WorkId
              GuidValue
              ProviderName
              Url
              Language {
                Link
                DisplayName
                Name
              }
              Expanded {
                ...ExpandedFields
                ContentLink {
                  __typename
                }
              }
            }
          }
        }
      }
    }
  }
}

fragment ExpandedFields on Content {
  __typename
  Name
  _fulltext
  _score
  ContentType
  Created
  Status
}

Incorporating the @recursive directive, the query can be simplified to a more succinct and understandable form:

query MyQuery {
        Content(locale: [en, sv]) {
          items {
            Created
            __typename
            Name
            ContentLink {
              ...ContentLinkFields
            }
          }
        }
      }

      fragment ContentLinkFields on ContentModelReference {
        Id
        WorkId
        GuidValue
        ProviderName
        Url
        Language {
          Link
          DisplayName
          Name
        }
        Expanded {
          ...ExpandedFields
          ContentLink @recursive(depth: 3) {
            __typename
          }
        }
      }

      fragment ExpandedFields on Content {
        __typename
        Name
        _fulltext
        _score
        ContentType
        Created
        Status
      }

In this simplified query, the @recursive directive has been applied to the ContentLink field with a specified depth of recursion. This significantly reduces the verbosity and repetition within the query, making it easier to maintain and comprehend.

The @recursive directive optimizes query composition when dealing with hierarchical structures, fostering cleaner and more efficient GraphQL schemas. By encapsulating complex recursive logic, it empowers developers to focus on crafting meaningful queries while enhancing overall code readability and maintainability.

How to use it

Applying the Directive:

The @recursive directive is used to simplify queries that involve recursive or deeply nested structures. You can apply it toprojection fields(the field must be an object) and inline fragments in your GraphQL queries.

Setting the Header Request:

Before making a request with the @recursive directive, ensure that you set the cg-recursive-enabled header request to true. This header is essential to enable the recursive behavior of the @recursive directive on the GraphQL server.

Example (using a tool like cURL):

curl -X POST \
  -H "Content-Type: application/json" \
  -H "cg-recursive-enabled: true" \
  --data '{ "query": "query { Content { title ...NestedContentFields @recursive(depth: 2) } }", "variables": {} }' \
  https://cg.optimizely.com/contennt/v2?auth={yourKey}

Specifying Depth:

By default, the @recursive directive assumes a depth level of 1, meaning that it will recursively retrieve data one level deep. However, you can customize the depth by providing the depth argument. The depth argument specifies how many levels of recursion you want to apply. The allowed range for depth is between 1 and 3.

Example:

query MyRecursiveQuery {
  Content {
    title
    nestedField @recursive(depth: 2) {
      name
    }
  }
}

Matching Field Types:

When using the @recursive directive, ensure that the field or inline fragment where you apply the directive matches the type of the most outer fragment. This is important to maintain proper type consistency throughout your query.

Example:

query MyRecursiveQuery {
  Content {
    title
    ...NestedContentFields
  }
}

fragment NestedContentFields on NestedContent {
  name
  nestedField @recursive(depth: 2) {
    value
  }
}

In this example, the NestedContentFields fragment must match the type of the Content field for the @recursive directive to work correctly.