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.

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
      }
    }
  }
}

References

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

Last modified September 24, 2024