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:

Directive Attached to Description
@include field, fragment inclusion Only include this field in the result if the argument is true.
@skip field, fragment inclusion Skip this field if the argument is true.

In addition, we provide custom directives:

Directive Attached to Description
@export field, fragment inclusion Export the value of a field into a variable that can be used somewhere else in the query.
@dependsOn field, fragment inclusion Specify 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
      }
    }
  }
}

The @dependsOn directive

The @dependsOn directive in GraphQL specifies that a field depends on another field. This directive can be used in the rare situations when fields are executed out of order due. Typically, fields are executed in the order they are defined in the query. However, in order to optimize the query execution, some requests are packed together before being sent to the back-end. This changes the order of execution as some fiels defined later in the query are executed before fields defined earlier. Moreoever, some fields depend on others because they use a variable set from an earlier field with the use of the @export directive.

Use the @dependsOn directive to ensure that a field is executed only after a previous field was executed.

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 January 30, 2025