Type checking of GraphQL query documents
The type checker carries out three tasks:
Make sure that types check. That is, the user supplies a well typed query document.
Make sure that types are properly inferred. Some times, the types the user supply needs an inference pass in order to figure out what the user supplied. The type-checker also infers the possible types and makes sure the query document is well typed.
Handle coercion for the constant fragment of a query document. Whenever a coercible constant value is encountered in a query document, or a coercible parameter occurs in a parameter, the type checker runs "input coercion" which is part canonicalization, part input validation on input data. The coerced value is expanded into the query document or parameter string, so the execution engine always works with coerced data. This choice is somewhat peculiar, but it serves an optimization purpose since we only have to carry out a coercion once for a query with constant values.
Polarity:
This type checker mentions polarity of types. There are 3 kinds of polarity: positive, negative and non-polar. The flows of these are that Client -> Server is positive and Server -> Client is negative. Non-polar types flows both ways. Since the server engine doesn't trust the client, type checking follows some polarity rules. If we check a positive polarity context, we don't trust the client and we use the schema data to verify that everything is covered by the client in a valid way. If we check in negative polarity context, we are the server and can trust things are correct. So we fold over the query document when considering if types are correct. Non-polar values fall naturally in both contexts.
Algorithm:
We use a bidirectional type checker. In general we handle two kinds of
typing constructs: G |- e ==> t (inference) and G |- e <== t, e (checking)
The first of these gets G,e as inputs and derives a t. The second form
gets G, e, and t as inputs and derives e' which is an e annotated with
more information.
| check/1 | |
| check_params/3 | |
| funenv/1 |
check(Document) -> any()
check_params(FunEnv, OpName, Params) -> any()
funenv(Ops) -> any()
Generated by EDoc