Hot Chocolatev12
This is documentation for v12, which is no longer actively maintained.
For up-to-date documentation, see the latest stable version.

Visitors

Hot Chocolate creates an abstract syntax tree for every incoming request. The execution engine evaluates this syntax tree in many different ways. Validation is a good example. Every incoming request has to be validated. The execution engine has to be sure that the semantics of the requested document are correct. A set of rules is applied to the syntax tree, to find potential semantic flaws.

Usually, you do not have to access the AST directly. The AST only becomes significant, when you want to change execution behavior based on the structure of the query. For example features like Filtering, Sorting, or Selection analyze the incoming query and generate expressions based on it.

Hot Chocolate provides you with different APIs that support you to traverse these trees. The SyntaxWalker is a visitor that has built-in all the logic to walk down a syntax tree.

The SyntaxWalker is completely stateless. All the state is on a context object that is passed along. The type of the context is denoted by the generic argument TContext in SyntaxWalker<TContext>.


Visitation

To start the visitation of a GraphQL syntax tree, you have to pass the node and the context that the visitation should start from to the visitor's Visit method. On its way down the syntax tree, the visitor enters a node. The visitor then gets the children of the current node and enters its children. Once the visitor reached a leaf node, it starts walking back up the tree and leaves all the nodes. The visitor provides virtual Enter and Leave methods for all GraphQL AST nodes. These methods are called from the visitor as it enters or leaves a node.

The syntax walker provides a few methods in addition to the Enter and Leave methods. For these two methods, there are convenience methods that are called right before and after the method call. Namely, OnBeforeEnter, OnAfterEnter, OnBeforeLeave, OnAfterLeave. These methods can modify the current TContext. These before and after methods are good places to initialize state that is used in the main enter or leave method. e.g. before entering a FieldNode, you may want to peek the latest type from the context and get the instance of the ObjectField corresponding to FieldNode of this type. You may also want to push this type onto the context to then use it in the Enter method.

⚠️ NOTE: In the following sequence diagram the participants do NOT represent any object instances. Furthermore, many steps are hidden in this example. The visualization below should just provide you visual insight on the order of the methods being called.

GraphQL
query GetFoos {
foo {
bar
}
}
RootFooBarOnBeforeEnter `query GetFoos`1Enter `query GetFoos`2OnAfterEnter `query GetFoos`3VisitChildren4OnBeforeEnter foo5Enter foo6OnAfterEnter foo7VisitChildren8...-9OnBeforeLeave foo10Leave foo11OnAfterLeave foo12-13OnBeforeLeave `query GetFoos`14Leave `query GetFoos`15OnAfterLeave `query GetFoos`16RootFooBar
  1. We start walking down the tree and enter.
  2. Call OnBeforeEnter(OperationDefinitionNode node, TContext context)
  3. Call Enter(OperationDefinitionNode node, TContext context)
  4. Call OnAfterEnter(OperationDefinitionNode node, TContext context)
  5. Call VisitChildren(OperationDefinitionNode node, TContext context)
  6. Call OnBeforeEnter(ObjectFieldNode node, TContext context)
  7. Call Enter(ObjectFieldNode node, TContext context)
  8. Call OnAfterEnter(ObjectFieldNode node, TContext context)
  9. Call VisitChildren(ObjectFieldNode node, TContext context)
  10. We walk back up the tree and leave
  11. Call OnBeforeLeave(ObjectFieldNode node, TContext context)
  12. Call Leave(ObjectFieldNode node, TContext context)
  13. Call OnAfterLeave(ObjectFieldNode node, TContext context)
  14. We walk back up the tree and leave.
  15. Call OnBeforeLeave(OperationDefinitionNode node, TContext context)
  16. Call Leave(OperationDefinitionNode node, TContext context)
  17. Call OnAfterLeave(OperationDefinitionNode node, TContext context)

Visitor Actions

The Enter and Leave methods return visitor actions. These methods control the visitor's next step in the visitation. Visitor actions can be used to skip further visitation and step back up, or to continue and walk the current branch of the tree further down.

Continue

Returning Continue from the Enter or Leave methods indicates that the visitation shall continue on the current branch.

In the following example Continue is returned from the onEnter method. The visitor calls VisitChildren and continues by entering the selection set.

GraphQL
query {
foo {
bar
baz @onEnter(return: CONTINUE) {
quux
}
qux
}
}

Skip

Returning Skip is returned from the Enter or Leave methods indicates that any further visitation on this node shall be stopped.

In the following example, Skip is returned from the onEnter method. The visitor skips the field baz. It continues visitation by entering the field qux:

GraphQL
query {
foo {
bar
baz @onEnter(return: SKIP) {
quux
}
qux
}
}

SkipAndLeave

Returning SkipAndLeave from the Enter method indicates that any further visitation on this node shall be stopped. Instead of directly calling the next Enter method, the visitor calls the Leave method of the current node first.

In the following example SkipAndLeave is returned from the onEnter method. The visitor skips the field baz. Before it continues visitation with the field qux it leaves the field baz by calling Leave:

GraphQL
query {
foo {
bar
baz @onEnter(return: SKIPANDLEAVE) {
quux
}
qux
}
}

Break

Returning Break is from the Enter or Leave methods indicates that any further visitation on this branch shall be stopped.

In the following example Break is returned from the onEnter method. The visitor immediately starts walking back up. The visitor calls the Leave on foo instead of visiting the selection set of baz it skips baz and qux.

GraphQL
query {
foo {
bar
baz @onEnter(return: BREAK) {
quux
}
qux
}
}