diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07fbf282f..786a85d89 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,7 +51,7 @@ move forward. See editor Lee Byron talk about Once a query is written, it should always mean the same thing and return the same shaped result. Future changes should not change the meaning of existing - schema or queries or in any other way cause an existing compliant GraphQL + schema or requests or in any other way cause an existing compliant GraphQL service to become non-compliant for prior versions of the spec. * **Performance is a feature** diff --git a/README.md b/README.md index 941c1e87b..2e818113b 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ type Droid implements Character { We're missing one last piece: an entry point into the type system. When we define a schema, we define an object type that is the basis for all -queries. The name of this type is `Query` by convention, and it describes +query operations. The name of this type is `Query` by convention, and it describes our public, top-level API. Our `Query` type for this example will look like this: diff --git a/spec/Section 1 -- Overview.md b/spec/Section 1 -- Overview.md index 5aa70ab3c..46c9b3d9f 100644 --- a/spec/Section 1 -- Overview.md +++ b/spec/Section 1 -- Overview.md @@ -26,7 +26,7 @@ Which produces the resulting data (in JSON): ``` GraphQL is not a programming language capable of arbitrary computation, but is -instead a language used to query application services that have +instead a language used to make requests to application services that have capabilities defined in this specification. GraphQL does not mandate a particular programming language or storage system for application services that implement it. Instead, application services take their capabilities and map them diff --git a/spec/Section 2 -- Language.md b/spec/Section 2 -- Language.md index 9f6eca2e2..1935975e7 100644 --- a/spec/Section 2 -- Language.md +++ b/spec/Section 2 -- Language.md @@ -3,7 +3,7 @@ Clients use the GraphQL query language to make requests to a GraphQL service. We refer to these request sources as documents. A document may contain operations (queries, mutations, and subscriptions) as well as fragments, a -common unit of composition allowing for query reuse. +common unit of composition allowing for data requirement reuse. A GraphQL document is defined as a syntactic grammar where terminal symbols are tokens (indivisible lexical units). These tokens are defined in a lexical @@ -337,8 +337,8 @@ under-fetching data. } ``` -In this query, the `id`, `firstName`, and `lastName` fields form a selection -set. Selection sets may also contain fragment references. +In this query operation, the `id`, `firstName`, and `lastName` fields form a +selection set. Selection sets may also contain fragment references. ## Fields @@ -438,7 +438,7 @@ Many arguments can exist for a given field: Arguments may be provided in any syntactic order and maintain identical semantic meaning. -These two queries are semantically identical: +These two operations are semantically identical: ```graphql example { @@ -546,7 +546,7 @@ query noFragments { ``` The repeated fields could be extracted into a fragment and composed by -a parent fragment or query. +a parent fragment or operation. ```graphql example query withFragments { @@ -567,8 +567,8 @@ fragment friendFields on User { } ``` -Fragments are consumed by using the spread operator (`...`). All fields selected -by the fragment will be added to the query field selection at the same level +Fragments are consumed by using the spread operator (`...`). All fields +selected by the fragment will be added to the field selection at the same level as the fragment invocation. This happens through multiple levels of fragment spreads. @@ -597,7 +597,7 @@ fragment standardProfilePic on User { } ``` -The queries `noFragments`, `withFragments`, and `withNestedFragments` all +The operations `noFragments`, `withFragments`, and `withNestedFragments` all produce the same response object. @@ -616,7 +616,7 @@ Fragments can be specified on object types, interfaces, and unions. Selections within fragments only return values when the concrete type of the object it is operating on matches the type of the fragment. -For example in this query on the Facebook data model: +For example in this operation using the Facebook data model: ```graphql example query FragmentTyping { @@ -1049,7 +1049,7 @@ literal representation of input objects as "object literals." Input object fields may be provided in any syntactic order and maintain identical semantic meaning. -These two queries are semantically identical: +These two operations are semantically identical: ```graphql example { @@ -1096,7 +1096,9 @@ If not defined as constant (for example, in {DefaultValue}), a {Variable} can be supplied for an input value. Variables must be defined at the top of an operation and are in scope -throughout the execution of that operation. +throughout the execution of that operation. Values for those variables are +provided to a GraphQL service as part of a request so they may be substituted +in during execution. In this example, we want to fetch a profile picture size based on the size of a particular device: @@ -1111,10 +1113,8 @@ query getZuckProfile($devicePicSize: Int) { } ``` -Values for those variables are provided to a GraphQL service along with a -request so they may be substituted during execution. If providing JSON for the -variables' values, we could run this query and request profilePic of -size `60` width: +If providing JSON for the variables' values, we could request a `profilePic` of +size `60`: ```json example { @@ -1124,11 +1124,10 @@ size `60` width: **Variable use within Fragments** -Query variables can be used within fragments. Query variables have global scope -with a given operation, so a variable used within a fragment must be declared -in any top-level operation that transitively consumes that fragment. If -a variable is referenced in a fragment and is included by an operation that does -not define that variable, the operation cannot be executed. +Variables can be used within fragments. Variables have global scope with a given operation, so a variable used within a fragment must be declared in any +top-level operation that transitively consumes that fragment. If a variable is +referenced in a fragment and is included by an operation that does not define +that variable, that operation is invalid (see [All Variable Uses Defined](#sec-All-Variable-Uses-Defined)). ## Type References @@ -1146,9 +1145,9 @@ NonNullType : - NamedType ! - ListType ! -GraphQL describes the types of data expected by query variables. Input types -may be lists of another input type, or a non-null variant of any other -input type. +GraphQL describes the types of data expected by arguments and variables. +Input types may be lists of another input type, or a non-null variant of any +other input type. **Semantics** @@ -1188,8 +1187,8 @@ including or skipping a field. Directives provide this by describing additional Directives have a name along with a list of arguments which may accept values of any input type. -Directives can be used to describe additional information for types, fields, fragments -and operations. +Directives can be used to describe additional information for types, fields, +fragments and operations. As future versions of GraphQL adopt new configurable execution capabilities, they may be exposed via directives. GraphQL services and tools may also provide diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 775cb9bc4..fe98bcb7b 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -1,9 +1,9 @@ # Type System The GraphQL Type system describes the capabilities of a GraphQL service and is -used to determine if a query is valid. The type system also describes the -input types of query variables to determine if values provided at runtime -are valid. +used to determine if a requested operation is valid, to guarantee the type of +response results, and describes the input types of variables to determine if +values provided at request time are valid. TypeSystemDocument : TypeSystemDefinition+ @@ -79,7 +79,7 @@ schema { } """ -Root type for all your queries +Root type for all your query operations """ type Query { """ @@ -191,7 +191,7 @@ When using the type system definition language, a document must include at most one {`schema`} definition. In this example, a GraphQL schema is defined with both query and mutation -root types: +root operation types: ```graphql example schema { @@ -424,8 +424,8 @@ raised (input values are validated before execution begins). GraphQL has different constant literals to represent integer and floating-point input values, and coercion rules may apply differently depending on which type -of input value is encountered. GraphQL may be parameterized by query variables, -the values of which are often serialized when sent over a transport like HTTP. Since +of input value is encountered. GraphQL may be parameterized by variables, the +values of which are often serialized when sent over a transport like HTTP. Since some common serializations (ex. JSON) do not discriminate between integer and floating-point values, they are interpreted as an integer input value if they have an empty fractional part (ex. `1.0`) and otherwise as floating-point @@ -601,14 +601,15 @@ FieldsDefinition : { FieldDefinition+ } FieldDefinition : Description? Name ArgumentsDefinition? : Type Directives[Const]? -GraphQL queries are hierarchical and composed, describing a tree of information. -While Scalar types describe the leaf values of these hierarchical queries, Objects -describe the intermediate levels. +GraphQL operations are hierarchical and composed, describing a tree of +information. While Scalar types describe the leaf values of these hierarchical +operations, Objects describe the intermediate levels. GraphQL Objects represent a list of named fields, each of which yield a value of a specific type. Object values should be serialized as ordered maps, where the -queried field names (or aliases) are the keys and the result of evaluating -the field is the value, ordered by the order in which they appear in the query. +selected field names (or aliases) are the keys and the result of evaluating +the field is the value, ordered by the order in which they appear in +the selection set. All fields defined within an Object type must not have a name which begins with {"__"} (two underscores), as this is used exclusively by GraphQL's @@ -687,8 +688,8 @@ type Person { } ``` -Valid queries must supply a nested field set for a field that returns -an object, so this query is not valid: +Valid operations must supply a nested field set for any field that returns an +object, so this operation is not valid: ```graphql counter-example { @@ -722,7 +723,7 @@ And will yield the subset of each object type queried: **Field Ordering** When querying an Object, the resulting mapping of fields are conceptually -ordered in the same order in which they were encountered during query execution, +ordered in the same order in which they were encountered during execution, excluding fragments for which the type does not apply and fields or fragments that are skipped via `@skip` or `@include` directives. This ordering is correctly produced when using the {CollectFields()} algorithm. @@ -920,10 +921,10 @@ type Person { } ``` -GraphQL queries can optionally specify arguments to their fields to provide +Operations can optionally specify arguments to their fields to provide these arguments. -This example query: +This example operation: ```graphql example { @@ -932,7 +933,7 @@ This example query: } ``` -May yield the result: +May return the result: ```json example { @@ -948,9 +949,9 @@ Object, Interface, or Union type). ### Field Deprecation Fields in an object may be marked as deprecated as deemed necessary by the -application. It is still legal to query for these fields (to ensure existing -clients are not broken by the change), but the fields should be appropriately -treated in documentation and tooling. +application. It is still legal to include these fields in a selection set +(to ensure existing clients are not broken by the change), but the fields should +be appropriately treated in documentation and tooling. When using the type system definition language, `@deprecated` directives are used to indicate that a field is deprecated: @@ -1062,7 +1063,7 @@ type Contact { } ``` -This allows us to write a query for a `Contact` that can select the +This allows us to write a selection set for a `Contact` that can select the common fields. ```graphql example @@ -1074,10 +1075,10 @@ common fields. } ``` -When querying for fields on an interface type, only those fields declared on +When selecting fields on an interface type, only those fields declared on the interface may be queried. In the above example, `entity` returns a `NamedEntity`, and `name` is defined on `NamedEntity`, so it is valid. However, -the following would not be a valid query: +the following would not be a valid selection set against `Contact`: ```graphql counter-example { @@ -1091,7 +1092,7 @@ the following would not be a valid query: because `entity` refers to a `NamedEntity`, and `age` is not defined on that interface. Querying for `age` is only valid when the result of `entity` is a -`Person`; the query can express this using a fragment or an inline fragment: +`Person`; this can be expressed using a fragment or an inline fragment: ```graphql example { @@ -1294,11 +1295,9 @@ type SearchQuery { } ``` -When querying the `firstSearchResult` field of type `SearchQuery`, the -query would ask for all fields inside of a fragment indicating the appropriate -type. If the query wanted the name if the result was a Person, and the height if -it was a photo, the following query is invalid, because the union itself -defines no fields: +In this example, a query operation wants the name if the result was a Person, +and the height if it was a photo. However because a union itself defines no +fields, this could be ambiguous and is invalid. ```graphql counter-example { @@ -1309,7 +1308,7 @@ defines no fields: } ``` -Instead, the query would be: +A valid operation includes typed fragments (in this example, inline fragments): ```graphql example { @@ -1415,7 +1414,7 @@ reasonable coercion is not possible they must raise a field error. GraphQL has a constant literal to represent enum input values. GraphQL string literals must not be accepted as an enum input and instead raise a request error. -Query variable transport serializations which have a different representation +Variable transport serializations which have a different representation for non-string symbolic values (for example, [EDN](https://github.com/edn-format/edn)) should only allow such values as enum input values. Otherwise, for most transport serializations that do not, strings may be interpreted as the enum @@ -1709,9 +1708,9 @@ exclamation mark is used to denote a field that uses a Non-Null type like this: **Nullable vs. Optional** -Fields are *always* optional within the context of a query, a field may be -omitted and the query is still valid. However fields that return Non-Null types -will never return the value {null} if queried. +Fields are *always* optional within the context of a selection set, a field may +be omitted and the selection set is still valid. However fields that return +Non-Null types will never return the value {null} if queried. Inputs (such as field arguments), are always optional by default. However a non-null input type is required. In addition to not accepting the value {null}, diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 4815b657f..a4ee7d11c 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -3,7 +3,7 @@ A GraphQL service supports introspection over its schema. This schema is queried using GraphQL itself, creating a powerful platform for tool-building. -Take an example query for a trivial app. In this case there is a User type with +Take an example request for a trivial app. In this case there is a User type with three fields: id, name, and birthday. For example, given a service with the following type definition: @@ -16,7 +16,7 @@ type User { } ``` -The query +A request containing the operation: ```graphql example { @@ -32,7 +32,7 @@ The query } ``` -would return +would produce the result: ```json example { @@ -221,11 +221,11 @@ enum __DirectiveLocation { ### The __Type Type `__Type` is at the core of the type introspection system, it represents all -types in the system: both named types (e.g. Scalars and Object types) and -type modifiers (e.g. List and Non-Null types). +types in the system: both named types (e.g. Scalars and Object types) and +type modifiers (e.g. List and Non-Null types). -Type modifiers are used to modify the type presented in the field `ofType`. -This modified type may recursively be a modified type, representing lists, +Type modifiers are used to modify the type presented in the field `ofType`. +This modified type may recursively be a modified type, representing lists, non-nullables, and combinations thereof, ultimately modifying a named type. ### Type Kinds @@ -259,7 +259,7 @@ Fields * `kind` must return `__TypeKind.OBJECT`. * `name` must return a String. * `description` may return a String or {null}. -* `fields`: The set of fields query-able on this type. +* `fields`: The set of fields that can be selected for this type. * Accepts the argument `includeDeprecated` which defaults to {false}. If {true}, deprecated fields are also returned. * `interfaces`: The set of interfaces that an object implements. @@ -367,8 +367,8 @@ A Non-Null type is a type modifier: it wraps another type instance in the `ofType` field. Non-null types do not allow {null} as a response, and indicate required inputs for arguments and input object fields. -The modified type in the `ofType` field may itself be a modified List type, -allowing the representation of Non-Null of Lists. However it must not be a +The modified type in the `ofType` field may itself be a modified List type, +allowing the representation of Non-Null of Lists. However it must not be a modified Non-Null type to avoid a redundant Non-Null of Non-Null. * `kind` must return `__TypeKind.NON_NULL`. diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 29225e491..f56c0f2d6 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -582,7 +582,7 @@ fragment conflictingDifferingResponses on Pet { **Explanatory Text** Field selections on scalars or enums are never allowed, because they -are the leaf nodes of any GraphQL query. +are the leaf nodes of any GraphQL operation. The following is valid. @@ -602,11 +602,12 @@ fragment scalarSelectionsNotAllowedOnInt on Dog { } ``` -Conversely the leaf field selections of GraphQL queries +Conversely the leaf field selections of GraphQL operations must be of type scalar or enum. Leaf selections on objects, interfaces, and unions without subfields are disallowed. -Let's assume the following additions to the query root type of the schema: +Let's assume the following additions to the query root operation type of +the schema: ```graphql example extend type Query { @@ -761,7 +762,7 @@ fragment goodNonNullArg on Arguments { The argument can be omitted from a field with a nullable argument. -Therefore the following query is valid: +Therefore the following fragment is valid: ```graphql example fragment goodBooleanArgDefault on Arguments { @@ -861,7 +862,7 @@ fragment fragmentOne on Dog { Fragments must be specified on types that exist in the schema. This applies for both named and inline fragments. If they are -not defined in the schema, the query does not validate. +not defined in the schema, the fragment is invalid. For example the following fragments are valid: @@ -1397,7 +1398,7 @@ which is not defined on the expected type: Input objects must not contain more than one field of the same name, otherwise an ambiguity would exist which includes an ignored portion of syntax. -For example the following query will not pass validation. +For example the following document will not pass validation. ```graphql counter-example { @@ -1466,7 +1467,7 @@ GraphQL services define what directives they support and where they support them For each usage of a directive, the directive must be used in a location that the service has declared support for. -For example the following query will not pass validation because `@skip` does +For example the following document will not pass validation because `@skip` does not provide `QUERY` as a valid location. ```graphql counter-example @@ -1496,7 +1497,7 @@ definition they apply to. When more than one directive of the same name is used, the expected metadata or behavior becomes ambiguous, therefore only one of each directive is allowed per location. -For example, the following query will not pass validation because `@skip` has +For example, the following document will not pass validation because `@skip` has been used twice for the same field: ```raw graphql counter-example @@ -1506,7 +1507,8 @@ query ($foo: Boolean = true, $bar: Boolean = false) { ``` However the following example is valid because `@skip` has been used only once -per location, despite being used twice in the query and on the same named field: +per location, despite being used twice in the operation and on the same +named field: ```raw graphql example query ($foo: Boolean = true, $bar: Boolean = false) { @@ -1596,7 +1598,7 @@ extend type Query { } ``` -The following queries are valid: +The following operations are valid: ```graphql example query takesBoolean($atOtherHomes: Boolean) { @@ -1616,7 +1618,7 @@ query TakesListOfBooleanBang($booleans: [Boolean!]) { } ``` -The following queries are invalid: +The following operations are invalid: ```graphql counter-example query takesCat($cat: Cat) { @@ -1666,7 +1668,7 @@ query variableIsDefined($atOtherHomes: Boolean) { is valid. ${atOtherHomes} is defined by the operation. -By contrast the following query is invalid: +By contrast the following document is invalid: ```graphql counter-example query variableIsNotDefined { @@ -1702,7 +1704,7 @@ since {isHousetrainedFragment} is used within the context of the operation operation. On the other hand, if a fragment is included within an operation that does -not define a referenced variable, the query is invalid. +not define a referenced variable, the document is invalid. ```graphql counter-example query variableIsNotDefinedUsedInSingleFragment { @@ -1999,7 +2001,7 @@ query booleanArgQueryWithDefault($booleanArg: Boolean) { In the example below, an optional variable `$booleanArg` is allowed to be used in the non-null argument (`nonNullBooleanArg`) because the variable provides -a default value in the query. This behavior is explicitly supported for +a default value in the operation. This behavior is explicitly supported for compatibility with earlier editions of this specification. GraphQL authoring tools may wish to report this as a warning with the suggestion to replace `Boolean` with `Boolean!` to avoid ambiguity. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 6292886ca..ace837f2e 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -112,15 +112,16 @@ Note: This algorithm is very similar to {CoerceArgumentValues()}. ## Executing Operations The type system, as described in the "Type System" section of the spec, must -provide a query root object type. If mutations or subscriptions are supported, -it must also provide a mutation or subscription root object type, respectively. +provide a query root operation type. If mutations or subscriptions are supported, +it must also provide a mutation or subscription root operation type, respectively. ### Query If the operation is a query, the result of the operation is the result of -executing the query’s top level selection set with the query root object type. +executing the operation’s top level selection set with the query root +operation type. -An initial value may be provided when executing a query. +An initial value may be provided when executing a query operation. ExecuteQuery(query, schema, variableValues, initialValue): @@ -137,7 +138,7 @@ ExecuteQuery(query, schema, variableValues, initialValue): ### Mutation If the operation is a mutation, the result of the operation is the result of -executing the mutation’s top level selection set on the mutation root +executing the operation’s top level selection set on the mutation root object type. This selection set should be executed serially. It is expected that the top level fields in a mutation operation perform @@ -162,8 +163,8 @@ If the operation is a subscription, the result is an event stream called the "Response Stream" where each event in the event stream is the result of executing the operation for each new event on an underlying "Source Stream". -Executing a subscription creates a persistent function on the service that -maps an underlying Source Stream to a returned Response Stream. +Executing a subscription operation creates a persistent function on the service +that maps an underlying Source Stream to a returned Response Stream. Subscribe(subscription, schema, variableValues, initialValue): @@ -335,7 +336,7 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues): * Set {responseValue} as the value for {responseKey} in {resultMap}. * Return {resultMap}. -Note: {resultMap} is ordered by which fields appear first in the query. This +Note: {resultMap} is ordered by which fields appear first in the operation. This is explained in greater detail in the Field Collection section below. **Errors and Non-Null Fields** @@ -562,8 +563,8 @@ Fields may include arguments which are provided to the underlying runtime in order to correctly produce a value. These arguments are defined by the field in the type system to have a specific input type. -At each argument position in a query may be a literal {Value}, or a {Variable} -to be provided at runtime. +At each argument position in an operation may be a literal {Value}, or a +{Variable} to be provided at runtime. CoerceArgumentValues(objectType, field, variableValues): * Let {coercedValues} be an empty unordered Map. @@ -608,7 +609,7 @@ CoerceArgumentValues(objectType, field, variableValues): * Return {coercedValues}. Note: Variable values are not coerced because they are expected to be coerced -before executing the operation in {CoerceVariableValues()}, and valid queries +before executing the operation in {CoerceVariableValues()}, and valid operations must only allow usage of variables of appropriate types. @@ -709,7 +710,7 @@ When more than one field of the same name is executed in parallel, their selection sets are merged together when completing the value in order to continue execution of the sub-selection sets. -An example query illustrating parallel fields with the same name with +An example operation illustrating parallel fields with the same name with sub-selections. ```graphql example diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index 959749ea3..e13a7c079 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -38,8 +38,9 @@ in a response during debugging. The `data` entry in the response will be the result of the execution of the requested operation. If the operation was a query, this output will be an -object of the schema's query root type; if the operation was a mutation, this -output will be an object of the schema's mutation root type. +object of the schema's query root operation type; if the operation was a +mutation, this output will be an object of the schema's mutation root +operation type. If an error was raised before execution begins, the `data` entry should not be present in the result. @@ -111,10 +112,10 @@ response and ending with the field associated with the error. Path segments that represent fields should be strings, and path segments that represent list indices should be 0-indexed integers. If the error happens in an aliased field, the path to the error should use the aliased name, since -it represents a path in the response, not in the query. +it represents a path in the response, not in the request. For example, if fetching one of the friends' names fails in the following -query: +operation: ```graphql example { @@ -296,8 +297,8 @@ JSON format throughout this document. Since the result of evaluating a selection set is ordered, the serialized Map of results should preserve this order by writing the map entries in the same order -as those fields were requested as defined by query execution. Producing a -serialized response where fields are represented in the same order in which +as those fields were requested as defined by selection set execution. Producing +a serialized response where fields are represented in the same order in which they appear in the request improves human readability during debugging and enables more efficient parsing of responses if the order of properties can be anticipated.