Directives

GraphQL directives modify query execution, including core directives like @include and @skip, and custom ones like @export.

Directives are a GraphQL feature that affect the execution of a query in any way the server desires. Directives can be attached to different parts of the schema (field, fragment inclusion, etc.). There are several core GraphQL directives:

DirectiveAttached toDescription
@includefield, fragment inclusionOnly include this field in the result if the argument is true.
@skipfield, fragment inclusionSkip this field if the argument is true.

In addition, we provide custom directives:

DirectiveAttached toDescription
@exportfield, fragment inclusionExport the value of a field into a variable that can be used somewhere else in the query.
@dependsOnfield, fragment inclusionSpecify that a field depends on another field.

The @include directive

Includes a field or fragment in the result only if the Boolean argument is true.

Syntax:

@include(if: Boolean!)

Example:

query($cid : Int!, $pagesize : Int, $withdetails : Boolean!)
{
  useCompany(no : $cid)
  {
    order(first : $pagesize)
    {
      totalCount
      items
      {
        orderNo
        orderDate

        lines : joindown_OrderLine_via_Order(first: 2) @include(if: $withdetails)
        {
          totalCount
          items
          {
            lineNo
            transactionDate
          }
        }
      }
    }
  }
}

Result:

$withdetails is false
{
  "data": {
    "useCompany": {
      "order": {
        "totalCount": 451,
        "items": [
          {
            "orderNo": 1,
            "orderDate": 20210212
          },
          {
            "orderNo": 2,
            "orderDate": 20130203
          }
        ]
      }
    }
  }
}
$withdetails is true
{
  "data": {
    "useCompany": {
      "order": {
        "totalCount": 451,
        "items": [
          {
            "orderNo": 1,
            "orderDate": 20210212,
            "lines": {
              "totalCount": 6,
              "items": [
                {
                  "lineNo": 1,
                  "transactionDate": 0
                },
                {
                  "lineNo": 2,
                  "transactionDate": 0
                }
              ]
            }
          },
          {
            "orderNo": 2,
            "orderDate": 20130203,
            "lines": {
              "totalCount": 5,
              "items": [
                {
                  "lineNo": 1,
                  "transactionDate": 20140904
                },
                {
                  "lineNo": 2,
                  "transactionDate": 20140904
                }
              ]
            }
          }
        ]
      }
    }
  }
}

The @skip directive

Skips a field if the Boolean argument is true.

Syntax:

@skip(if: Boolean!)

Example:

query($cid : Int!, $pagesize : Int, $nodetails : Boolean!)
{
  useCompany(no : $cid)
  {
    order(first : $pagesize)
    {
      totalCount
      items
      {
        orderNo
        orderDate

        lines : joindown_OrderLine_via_Order(first: 2) @skip(if: $nodetails)
        {
          totalCount
          items
          {
            lineNo
            transactionDate
          }
        }
      }
    }
  }
}

Result:

$nodetails is true
{
  "data": {
    "useCompany": {
      "order": {
        "totalCount": 451,
        "items": [
          {
            "orderNo": 1,
            "orderDate": 20210212
          },
          {
            "orderNo": 2,
            "orderDate": 20130203
          }
        ]
      }
    }
  }
}
$nodetails is false
{
  "data": {
    "useCompany": {
      "order": {
        "totalCount": 451,
        "items": [
          {
            "orderNo": 1,
            "orderDate": 20210212,
            "lines": {
              "totalCount": 6,
              "items": [
                {
                  "lineNo": 1,
                  "transactionDate": 0
                },
                {
                  "lineNo": 2,
                  "transactionDate": 0
                }
              ]
            }
          },
          {
            "orderNo": 2,
            "orderDate": 20130203,
            "lines": {
              "totalCount": 5,
              "items": [
                {
                  "lineNo": 1,
                  "transactionDate": 20140904
                },
                {
                  "lineNo": 2,
                  "transactionDate": 20140904
                }
              ]
            }
          }
        ]
      }
    }
  }
}

The @export directive

The @export directive in GraphQL exports the value of a field into a variable that is used somewhere else in the query. This can be either a single value or an array.

Syntax:

@export(as: "variablename", distinct : true)

Example: Fetch the cutomer number of the associate whose indentifier is specified and then use the customer number to fetch orders.

Query
query($cid : Int!,
      $ano : Int!,
      $pagesize: Int,
      $customerId : Int = 0)
{
  useCompany(no: $cid)
  {
    associate(filter : {associateNo : {_eq: $ano}})
    {
      items
      {
        customerNo @export(as: "customerId")
      }
    }
    order(first : $pagesize,
          filter : {customerNo : {_eq : $customerId}})
    {
      totalCount
      items
      {
        orderNo
        orderDate
        customerNo
      }
    }
  }
}
Result
{
  "data": {
    "useCompany": {
      "associate": {
        "items": [
          {
            "customerNo": 10000
          }
        ]
      },
      "order": {
        "totalCount": 14,
        "items": [
          {
            "orderNo": 81,
            "orderDate": 20150115,
            "customerNo": 10000
          }
        ]
      }
    }
  }
}

Example: Add one order and two order lines for the order with a single request.

Query
mutation ($cid: Int,
          $cno : Int,
          $pid1 : String,
          $pid2 : String,
          $orderId: Int = 0)
{
  useCompany(no: $cid)
  {
    order_create(
      values: [
        {
          orderDate: 20221104,
          customerNo: $cno,
          orderType: 1,
          transactionType: 1
        }
      ]
    )
    {
      affectedRows
      items
      {
        orderNo @export(as: "orderId")
      }
    }
    orderLine_create(
      values: [
        {
          orderNo: $orderId,
          productNo: $pid1,
          quantity: 1
        },
        {
          orderNo: $orderId,
          productNo: $pid2,
          quantity: 2
        }
      ]
    )
    {
      affectedRows
      items
      {
        lineNo
        orderNo
        productNo
      }
    }
  }
}
Result
{
  "data": {
    "useCompany": {
      "order_create": {
        "affectedRows": 1,
        "items": [
          {
            "orderNo": 632
          }
        ]
      },
      "orderLine_create": {
        "affectedRows": 2,
        "items": [
          {
            "lineNo": 1,
            "orderNo": 632,
            "productNo": "1001"
          },
          {
            "lineNo": 2,
            "orderNo": 632,
            "productNo": "1002"
          }
        ]
      }
    }
  }
}

There are several things to keep in mind when using this directive:

  • The variable into which the field value is exported must be defined in the query parameter list. Otherwise, when you use the variable later on in another part of the query, the server will complain that it is not defined.
  • You can only export the value of one field into one variable. If you attempt to write values from multiple fields into the same variable they will be overwritten based of the order of evaluation.
  • If you export multiple values into the same variable, the last field that is evaluated will define the value of the variable.
  • If the variable is defined as an array, you can store multiple values.

In the previous examples, we have used a variable that could store a single value. Therefore, if a query returned multiple elements, a field would get evaluated multiple times and each time the variable would be overritten. The value from the last evaluation is the one that is finally stored in the variable.

However, all the values can be preserved in an array. The only change is that you need to define the variable of an array type. Moreover, you can use the Boolean optional argument distinct to retain only the distict values and discard duplicates. An array variable can be used for instance with the _in and _not_in filters.

The following example shows a query that fetches information about all the orders that have lines that were updated after a given moment in time:

query read_modified_orders($cid : Int!, $dt : DateTime,
                           $ono : [Int] = [])
{
  useCompany(no : $cid)
  {
    orderLine(filter : {changedDateTime : {_gt : $dt}})
    {
      items
      {
        orderNo @export(as : "ono", distict : true)
      }
    }

    order(filter : {orderNo : {_in : $ono})
    {
      items
      {
        orderNo
        orderDate
        customerNo
      }
    }
  }
}

Ordering and @export

In most cases the consuming field references the exported variable in its arguments, either directly or nested inside an input object or list. When that happens, the server picks up the reference and evaluates the consuming field after the exporting one. The examples above work this way: the order(filter: {customerNo: {_eq: $customerId}}) argument references the customerId exported just above it, and orderLine_create does the same with orderId.

For ordering requirements that are not visible from the arguments, use @dependsOn, described next.

The @dependsOn directive

The @dependsOn directive specifies that a field depends on another field and must be executed after it. To optimize execution the server packs independent fields together before sending them to the back-end, which can shuffle the visible order of fields in the query. Argument-driven dependencies (including those introduced by @export) are sequenced automatically, so @dependsOn is reserved for cases where one field has a side effect that a later field relies on, but neither passes a variable to the other.

The example below shows this case: uploadToFileService does not reference the $batchId exported by batch_create, but it must still run after addNewDocument has registered the document, so the ordering is declared explicitly.

Syntax:

@dependsOn(field: "name")

Example:

mutation CreateBatchWithAttachment ($cid: Int,
                                    $batchId: Int = 0,
                                    $fina: String,
                                    $fiby: String,
                                    $tok: String)
{
  useCompany(no: $cid) {
    # create the batch
    batch_create(
      values: {
        voucherSeriesNo: 1,
        valueDate: 20250121
        description: "Demo batch"
      }
    )
    {
      affectedRows
      items {
        batchNo @export(as: "batchId")
      }
    }

    # create the voucher
    voucher_create(
      values: {
        batchNo: $batchId
        voucherDate: null
        voucherType: 21
        voucherNo: null
        debitAccountNo: 5000
        creditAccountNo: 1920
        amountDomestic: 500.00
        text: "first voucherline"
      }
    )
    {
      affectedRows
      items {
        batchNo
        voucherNo
    }

    # add a document to the batch
    voucher_processings {
      addNewDocument(
        filter: {batchNo: {_eq: $batchId}},
        args: {
          fileName: $fina,
          fileBytes: $fiby
        }
      )
      {
        succeeded
      }
    }

    # upload the document to the file service
    incomingAccountingDocumentAttachment_processings {
      uploadToFileService(
        filter: {fileName: {_eq: $fina}},
        args: {connectToken: $tok}
      ) @dependsOn(field: "addNewDocument")
      {
        succeeded
      }
    }
  }
}

References

You can learn more about the core GraphQL directives from these articles:

Last modified May 19, 2026