Showing preview only (683K chars total). Download the full file or copy to clipboard to get everything.
Repository: graphql/graphql-spec
Branch: main
Commit: 3c6695ce9cba
Files: 31
Total size: 661.9 KB
Directory structure:
gitextract_yl1f9z0u/
├── .github/
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── algorithm-format-check.mjs
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .prettierignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── STYLE_GUIDE.md
├── build.sh
├── changelogs/
│ ├── October2021.md
│ └── September2025.md
├── cspell.yml
├── package.json
├── scripts/
│ ├── generate-contributor-list.mjs
│ └── update-appendix-specified-definitions.mjs
├── signed-agreements/
│ └── README.md
└── spec/
├── Appendix A -- Conformance.md
├── Appendix B -- Notation Conventions.md
├── Appendix C -- Grammar Summary.md
├── Appendix D -- Specified Definitions.md
├── GraphQL.md
├── Section 1 -- Overview.md
├── Section 2 -- Language.md
├── Section 3 -- Type System.md
├── Section 4 -- Introspection.md
├── Section 5 -- Validation.md
├── Section 6 -- Execution.md
├── Section 7 -- Response.md
└── metadata.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
!!! IMPORTANT !!!
Before creating your issue:
- Have a question? Find community resources at https://graphql.org/community/
- Find an editing mistake? Create a Pull Request with the edited fix! The Github
UI allows you to edit files directly, find the source files at:
https://github.com/graphql/graphql-spec/tree/master/spec
- Improvements to documentation? Head over to
https://github.com/graphql/graphql.github.io
- Feature request? First read
https://github.com/graphql/graphql-spec/blob/master/CONTRIBUTING.md and prefer
creating a Pull Request!
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
!!! IMPORTANT !!!
Please Read https://github.com/graphql/graphql-spec/blob/master/CONTRIBUTING.md
before creating a Pull Request.
================================================
FILE: .github/algorithm-format-check.mjs
================================================
import { readFile, readdir } from "node:fs/promises";
const SPEC_DIR = new URL("../spec", import.meta.url).pathname;
/** @see {@link https://spec-md.com/#sec-Value-Literals} */
const valueLiteralsRegexp = /\{((?:[^{}]|(?:\{[^{}]*\}))+)\}/g;
process.exitCode = 0;
const filenames = await readdir(SPEC_DIR);
for (const filename of filenames) {
if (!filename.endsWith(".md")) {
continue;
}
const markdown = await readFile(`${SPEC_DIR}/${filename}`, "utf8");
/**
* Not strictly 'lines' since we try and group indented things together as if
* they were one line. Close enough though.
*/
const lines = markdown.split(/\n(?=[\S\n]|\s*(?:-|[0-9]+\.) )/);
for (let i = 0, l = lines.length; i < l; i++) {
const line = lines[i];
// Check algorithm is consistently formatted
{
// Is it an algorithm definition?
const matches = line.match(/^([a-z0-9A-Z]+)(\s*)\(([^)]*)\)(\s*):(\s*)$/);
const grammarMatches =
filename === "Section 2 -- Language.md" &&
line.match(/^([A-Za-z0-9]+) ::?\s+((\S).*)$/);
if (matches) {
const [, algorithmName, ns1, _args, ns2, ns3] = matches;
if (ns1 || ns2 || ns3) {
console.log(
`Bad whitespace in definition of ${algorithmName} in '${filename}':`
);
console.dir(line);
console.log();
process.exitCode = 1;
}
if (lines[i + 1] !== "") {
console.log(
`No empty space after algorithm ${algorithmName} header in '${filename}'`
);
console.log();
process.exitCode = 1;
}
for (let j = i + 2; j < l; j++) {
const step = lines[j];
if (!step.match(/^\s*(-|[0-9]+\.) /)) {
if (step !== "") {
console.log(
`Bad algorithm ${algorithmName} step in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
break;
}
if (!step.match(/[.:]$/)) {
console.log(
`Bad formatting for '${algorithmName}' step (does not end in '.' or ':') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
if (step.match(/^\s*(-|[0-9]+\.)\s+[a-z]/)) {
console.log(
`Bad formatting of '${algorithmName}' step (should start with a capital) in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
const assertMatch = step.match(/^\s*(-|[0-9]+\.)\s*Assert([^:])/);
if (assertMatch) {
console.log(
`Bad formatting of '${algorithmName}' step (Assert should be immediately followed by ':'; found '${assertMatch[2]}') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
const stepWithoutValueLiterals = step.replace(
valueLiteralsRegexp,
""
);
if (stepWithoutValueLiterals.match(/\b[A-Z][A-Za-z0-9]+\(/)) {
console.log(
`Bad formatting of '${algorithmName}' step (algorithm call should be wrapped in braces: \`{MyAlgorithm(a, b, c)}\`) in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
const valueLiterals = step.matchAll(valueLiteralsRegexp, "");
for (const lit of valueLiterals) {
const inner = lit[1];
if (inner.includes("{")) {
console.log(
`Bad formatting of '${algorithmName}' step (algorithm call should not contain braces: \`${lit}\`) in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
}
const trimmedInnerLine = step.replace(/\s+/g, " ");
if (
trimmedInnerLine.match(
/(?:[rR]eturn|is (?:not )?)(true|false|null)\b/
) &&
!trimmedInnerLine.match(/null or empty/)
) {
console.log(
`Potential bad formatting of '${algorithmName}' step (true/false/null should be wrapped in curly braces, e.g. '{true}') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
}
} else if (grammarMatches) {
// This is super loosey-goosey
const [, grammarName, rest] = grammarMatches;
if (rest.trim() === "one of") {
// Still grammar, not algorithm
continue;
}
if (rest.trim() === "" && lines[i + 1] !== "") {
console.log(
`No empty space after grammar ${grammarName} header in '${filename}'`
);
console.log();
process.exitCode = 1;
}
while (lines[i + 1].trim() !== "") {
// Continuation of definition
i++;
}
if (!lines[i + 2].startsWith("- ")) {
// Not an algorithm; probably more grammar
continue;
}
for (let j = i + 2; j < l; j++) {
const step = lines[j];
if (!step.match(/^\s*(-|[0-9]+\.) /)) {
if (step !== "") {
console.log(`Bad grammar ${grammarName} step in '${filename}':`);
console.dir(step);
console.log();
process.exitCode = 1;
}
break;
}
if (!step.match(/[.:]$/)) {
console.log(
`Bad formatting for '${grammarName}' step (does not end in '.' or ':') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
if (step.match(/^\s*(-|[0-9]\.)\s+[a-z]/)) {
console.log(
`Bad formatting of '${grammarName}' step (should start with a capital) in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
const trimmedInnerLine = step.replace(/\s+/g, " ");
if (
trimmedInnerLine.match(
/(?:[rR]eturn|is (?:not )?)(true|false|null)\b/
) &&
!trimmedInnerLine.match(/null or empty/)
) {
console.log(
`Potential bad formatting of '${grammarName}' step (true/false/null should be wrapped in curly braces, e.g. '{true}') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
const assertMatch = step.match(/^\s*(-|[0-9]+\.)\s*Assert([^:])/);
if (assertMatch) {
console.log(
`Bad formatting of '${grammarName}' step (Assert should be immediately followed by ':'; found '${assertMatch[2]}') in '${filename}':`
);
console.dir(step);
console.log();
process.exitCode = 1;
}
}
}
}
// Check `- ...:` step is followed by an indent
{
const matches = line.match(/^(\s*)- .*:\s*$/);
if (matches) {
const indent = matches[1];
const nextLine = lines[i + 1];
if (!nextLine.startsWith(`${indent} `)) {
console.log(
`Lacking indent in '${filename}' following ':' character:`
);
console.dir(line);
console.dir(nextLine);
console.log();
// TODO: process.exitCode = 1;
}
}
}
}
}
if (process.exitCode === 0) {
console.log(`Everything looks okay!`);
} else {
console.log(`Please resolve the errors detailed above.`);
}
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- main
pull_request:
jobs:
test-spelling:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run test:spelling
test-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run test:format
- run: npm run test:algorithm-format
test-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run test:build
publish:
if: github.ref == 'refs/heads/main'
needs:
- test-spelling
- test-format
- test-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
keep_files: true
cname: spec.graphql.org
user_name: "github-actions[bot]"
user_email: "github-actions[bot]@users.noreply.github.com"
================================================
FILE: .gitignore
================================================
*.swp
*~
.*.haste_cache.*
.DS_Store
npm-debug.log
/build
/public
/gh-pages
/node_modules
================================================
FILE: .prettierignore
================================================
*.swp
*~
.*.haste_cache.*
.DS_Store
npm-debug.log
/build
/changelogs
/out
/gh-pages
/node_modules
/package.json
================================================
FILE: CONTRIBUTING.md
================================================
# GraphQL Specification Contribution Guide
GraphQL is still an evolving language. This repository contains the
specification text as well as Pull Requests with suggested improvements and
contributions.
Contributions that do not change the interpretation of the spec but instead
improve legibility, fix editorial errors, clear up ambiguity and improve
examples are encouraged. These "editorial changes" will normally be given the
["✏ Editorial" label](https://github.com/graphql/graphql-spec/issues?q=sort%3Aupdated-desc+is%3Aopen+label%3A%22%E2%9C%8F%EF%B8%8F+Editorial%22)
and are often merged by a spec editor with little process.
However, contributions that _do_ meaningfully change the interpretation of the
spec must follow an RFC (Request For Comments) process led by a _champion_
through a series of _stages_ intended to improve _visibility_, allow for
_discussion_ to reach the best solution, and arrive at _consensus_. This process
becomes ever more important as GraphQL's community broadens.
When proposing or weighing-in on any issue or pull request, consider the
[Code of Conduct](https://github.com/graphql/foundation/blob/main/CODE-OF-CONDUCT.md)
to better understand expected and unacceptable behavior.
## Contributing to GraphQL Libraries
A common point of confusion for those who wish to contribute to GraphQL is where
to start. In fact, you may have found yourself here after attempting to make an
improvement to a GraphQL library. Should a new addition be made to the GraphQL
spec first or a GraphQL library first? Admittedly, this can become a bit of a
[chicken-or-egg](https://en.wikipedia.org/wiki/Chicken_or_the_egg) dilemma.
GraphQL libraries seek to be "spec compliant", which means they discourage
changes that cause them to behave differently from the spec as written. However,
they also encourage pull requests for changes that accompany an RFC _proposal_
or RFC _draft_. In fact, a spec contribution RFC won't be _accepted_ until it
has experience being implemented in a GraphQL library.
To allow a library to remain spec compliant while also implementing _proposals_
and _drafts_, the library's maintainers may request that these new features are
disabled by default with opt-in option flags or they may simply wait to merge a
well-tested pull request until the spec proposal is _accepted_.
## Guiding Principles
GraphQL's evolution is guided by a few principles. Suggested contributions
should use these principles to guide the details of an RFC and decisions to move
forward. See editor Lee Byron talk about
[guiding principles at GraphQL Europe 2017](https://youtu.be/mePT9MNTM98?t=17m9s).
- **Backwards compatibility**
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 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**
GraphQL typically avoids syntax or behaviors that could jeopardize runtime
efficiency, or that make demands of GraphQL services which cannot efficiently
be fulfilled.
- **Favor no change**
As GraphQL is implemented in over a dozen languages under the collaboration of
hundreds of individuals, incorporating any change has a high cost.
Accordingly, proposed changes must meet a very high bar of added value. The
burden of proof is on the contributor to illustrate this value.
- **Enable new capabilities motivated by real use cases**
Every change should intend on unlocking a real and reasonable use case. Real
examples are always more compelling than theoretical ones, and common
scenarios are more compelling than rare ones. RFCs should do more than offer a
different way to reach an already achievable outcome.
- **Simplicity and consistency over expressiveness and terseness**
Plenty of behaviors and patterns found in other languages are intentionally
absent from GraphQL. "Possible but awkward" is often favored over more complex
alternatives. Simplicity (e.g. fewer concepts) is more important than
expressing more sophisticated ideas or writing less.
- **Preserve option value**
It's hard to know what the future brings; whenever possible, decisions should
be made that allow for more options in the future. Sometimes this is
unintuitive: spec rules often begin more strict than necessary with a future
option to loosen when motivated by a real use case.
- **Understandability is just as important as correctness**
The GraphQL spec, despite describing technical behavior, is intended to be
read by people. Use natural tone and include motivation and examples.
## RFC Contribution Champions
Contributing to GraphQL requires a lot of dedicated work. To set clear
expectations and provide accountability, each proposed RFC (request for
comments) must have a _champion_ who is responsible for addressing feedback and
completing next steps. An RFC may have multiple _champions_. The spec editors
are not responsible for completing RFCs which lack a _champion_ (though an
editor may be a _champion_ for an RFC).
An RFC which does not have a _champion_ may not progress through stages, and can
become stale. Stale proposals may be picked up by a new _champion_ or may be
_rejected_.
## RFC Contribution Stages
RFCs are guided by a _champion_ through a series of stages: _strawman_,
_proposal_, _draft_, and _accepted_ (or _rejected_), each of which has suggested
entrance criteria and next steps detailed below. RFCs typically advance one
stage at a time, but may advance multiple stages at a time. Stage advancements
typically occur during [Working Group](https://github.com/graphql/graphql-wg)
meetings, but may also occur on GitHub.
In general, it's preferable to start with a pull request so that we can best
evaluate the RFC in detail. However, starting with an issue is also permitted if
the full details are not worked out.
All RFCs start as either a _strawman_ or _proposal_.
## Stage 0: _Strawman_
An RFC at the _strawman_ stage captures a described problem or
partially-considered solutions. A _strawman_ does not need to meet any entrance
criteria. A _strawman's_ goal is to prove or disprove a problem and guide
discussion towards either rejection or a preferred solution. A _strawman_ may be
an issue or a pull request (though an illustrative pull request is preferrable).
_There is no entrance criteria for a Strawman_
As implied by the name
[strawman](https://en.wikipedia.org/wiki/Straw_man_proposal), the goal at this
stage is to knock it down (_reject_) by considering other possible related
solutions, showing that the motivating problem can be solved with no change to
the specification, or that it is not aligned with the _guiding principles_.
Once determined that the _strawman_ is compelling, it should seek the entrance
criteria for _proposal_.
## Stage 1: _Proposal_
An RFC at the _proposal_ stage is a solution to a problem with enough fidelity
to be discussed in detail. It must be backed by a willing _champion_. A
_proposal_'s goal is to make a compelling case for acceptance by describing both
the problem and the solution via examples and spec edits. A _proposal_ should be
a pull request.
_Entrance criteria:_
- Identified _champion_
- Clear explanation of problem and solution
- Illustrative examples
- Incomplete spec edits
- Identification of potential concerns, challenges, and drawbacks
A _proposal_ is subject to the same discussion as a _strawman_: ensuring that it
is well aligned with the _guiding principles_, is a problem worth solving, and
is the preferred solution to that problem. A _champion_ is not expected to have
confidence in every detail at this stage and should instead focus on identifying
and resolving issues and edge-cases. To better understand the technical
ramifications of the _proposal_, a _champion_ is encouraged to implement it in a
GraphQL library.
Most _proposals_ are expected to evolve or change and may be rejected.
Therefore, it is unwise to rely on a _proposal_ in a production GraphQL service.
GraphQL libraries _may_ implement _proposals_, though are encouraged to not
enable the _proposed_ feature without explicit opt-in.
## Stage 2: _Draft_
An RFC at the _draft_ stage is a fully formed solution. There is working group
consensus the problem identified should be solved, and this particular solution
is preferred. A _draft's_ goal is to precisely and completely describe the
solution and resolve any concerns through library implementations. A _draft_
must be a pull request.
_Entrance criteria:_
- Consensus the solution is preferred (typically via Working Group)
- Resolution of identified concerns and challenges
- Precisely described with spec edits
- Compliant implementation in GraphQL.js (might not be merged)
A _proposal_ becomes a _draft_ when the set of problems or drawbacks have been
fully considered and accepted or resolved, and the solution is deemed desirable.
A _draft_'s goal is to complete final spec edits that are ready to be merged and
implement the _draft_ in GraphQL libraries along with tests to gain confidence
that the spec text is sufficient.
_Drafts_ may continue to evolve and change, occasionally dramatically, and are
not guaranteed to be accepted. Therefore, it is unwise to rely on a _draft_ in a
production GraphQL Service. GraphQL libraries _should_ implement _drafts_ to
provide valuable feedback, though are encouraged not to enable the _draft_
feature without explicit opt-in when possible.
## Stage 3: _Accepted_
An RFC at the _accepted_ stage is a completed solution. According to a spec
editor it is ready to be merged as-is into the spec document. The RFC is ready
to be deployed in GraphQL libraries. An _accepted_ RFC must be implemented in
GraphQL.js.
_Entrance criteria:_
- Consensus the solution is complete (via editor or working group)
- Complete spec edits, including examples and prose
- Compliant implementation in GraphQL.js (fully tested and merged or ready to
merge)
A _draft_ is _accepted_ when the working group or editor has been convinced via
implementations and tests that it appropriately handles all edge cases; that the
spec changes not only precisely describe the new syntax and semantics but
include sufficient motivating prose and examples; and that the RFC includes
edits to any other affected areas of the spec. Once _accepted_, its _champion_
should encourage adoption of the RFC by opening issues or pull requests on other
popular GraphQL libraries.
An _accepted_ RFC is merged into the GraphQL spec's main branch by an editor and
will be included in the next released revision.
## Stage X: _Rejected_
An RFC may be _rejected_ at any point and for any reason. Most rejections occur
when a _strawman_ is proven to be unnecessary, is misaligned with the _guiding
principles_, or fails to meet the entrance criteria to become a _proposal_. A
_proposal_ may become _rejected_ for similar reasons as well as if it fails to
reach consensus or loses the confidence of its _champion_. Likewise a _draft_
may encounter unforeseen issues during implementations which cause it to lose
consensus or the confidence of its _champion_.
RFCs which have lost a _champion_ will not be _rejected_ immediately, but may
become _rejected_ if they fail to attract a new _champion_.
Once _rejected_, an RFC will typically not be reconsidered. Reconsideration is
possible if a _champion_ believes the original reason for rejection no longer
applies due to new circumstances or new evidence.
================================================
FILE: LICENSE.md
================================================
# Appendix: Copyright and Licensing
The GraphQL Specification Project is made available by the
[Joint Development Foundation](https://www.jointdevelopment.org/) Projects, LLC,
GraphQL Series. The current
[Working Group](https://github.com/graphql/graphql-wg) charter, which includes
the IP policy governing all working group deliverables (including
specifications, source code, and datasets) may be found at
[https://technical-charter.graphql.org](https://technical-charter.graphql.org).
**Copyright Notice**
Copyright © 2015-2018, Facebook, Inc.
Copyright © 2019-present, GraphQL contributors
THESE MATERIALS ARE PROVIDED “AS IS”. The parties expressly disclaim any
warranties (express, implied, or otherwise), including implied warranties of
merchantability, non-infringement, fitness for a particular purpose, or title,
related to the materials. The entire risk as to implementing or otherwise using
the materials is assumed by the implementer and user. IN NO EVENT WILL THE
PARTIES BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES
OF ACTION OF ANY KIND WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING
AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR
OTHERWISE, AND WHETHER OR NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
**Licensing**
The licenses for the GraphQL Specification Project are:
| Deliverable | License |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Specifications | [Open Web Foundation Agreement 1.0 (Patent and Copyright Grants)](https://www.openwebfoundation.org/the-agreements/the-owf-1-0-agreements-granted-claims/owfa-1-0) |
| Source code | [MIT License](https://opensource.org/licenses/MIT) |
| Data sets | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) |
================================================
FILE: README.md
================================================
[](https://graphql.org/)
# GraphQL
<img alt="GraphQL Logo" align="right" src="https://graphql.org/img/logo.svg" width="15%" />
The GraphQL specification is edited in the markdown files found in
[`/spec`](./spec) the latest release of which is published at
https://graphql.github.io/graphql-spec/.
The latest draft specification can be found at
https://graphql.github.io/graphql-spec/draft/ which tracks the latest commit to
the main branch in this repository.
Previous releases of the GraphQL specification can be found at permalinks that
match their [release tag](https://github.com/graphql/graphql-spec/releases). For
example, https://graphql.github.io/graphql-spec/October2016/. If you are linking
directly to the GraphQL specification, it's best to link to a tagged permalink
for the particular referenced version.
## Overview
This is a Working Draft of the Specification for GraphQL, a query language for
APIs created by Facebook.
The target audience for this specification is not the client developer, but
those who have, or are actively interested in, building their own GraphQL
implementations and tools.
In order to be broadly adopted, GraphQL will have to target a wide variety of
backend environments, frameworks, and languages, which will necessitate a
collaborative effort across projects and organizations. This specification
serves as a point of coordination for this effort.
Looking for help? Find resources
[from the community](https://graphql.org/community/).
## Getting Started
GraphQL consists of a type system, query language and execution semantics,
static validation, and type introspection, each outlined below. To guide you
through each of these components, we've written an example designed to
illustrate the various pieces of GraphQL.
This example is not comprehensive, but it is designed to quickly introduce the
core concepts of GraphQL, to provide some context before diving into the more
detailed specification or the
[GraphQL.js](https://github.com/graphql/graphql-js) reference implementation.
The premise of the example is that we want to use GraphQL to query for
information about characters and locations in the original Star Wars trilogy.
### Type System
At the heart of any GraphQL implementation is a description of what types of
objects it can return, described in a GraphQL type system and returned in the
GraphQL Schema.
For our Star Wars example, the
[starWarsSchema.ts](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsSchema.ts)
file in GraphQL.js defines this type system.
The most basic type in the system will be `Human`, representing characters like
Luke, Leia, and Han. All humans in our type system will have a name, so we
define the `Human` type to have a field called "name". This returns a String,
and we know that it is not null (since all `Human`s have a name), so we will
define the "name" field to be a non-nullable String. Using a shorthand notation
that we will use throughout the spec and documentation, we would describe the
human type as:
```graphql
type Human {
name: String
}
```
This shorthand is convenient for describing the basic shape of a type system;
the JavaScript implementation is more full-featured, and allows types and fields
to be documented. It also sets up the mapping between the type system and the
underlying data; for a test case in GraphQL.js, the underlying data is a
[set of JavaScript objects](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsData.ts),
but in most cases the backing data will be accessed through some service, and
this type system layer will be responsible for mapping from types and fields to
that service.
A common pattern in many APIs, and indeed in GraphQL is to give objects an ID
that can be used to refetch the object. So let's add that to our Human type.
We'll also add a string for their home planet.
```graphql
type Human {
id: String
name: String
homePlanet: String
}
```
Since we're talking about the Star Wars trilogy, it would be useful to describe
the episodes in which each character appears. To do so, we'll first define an
enum, which lists the three episodes in the trilogy:
```graphql
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
```
Now we want to add a field to `Human` describing what episodes they were in.
This will return a list of `Episode`s:
```graphql
type Human {
id: String
name: String
appearsIn: [Episode]
homePlanet: String
}
```
Now, let's introduce another type, `Droid`:
```graphql
type Droid {
id: String
name: String
appearsIn: [Episode]
primaryFunction: String
}
```
Now we have two types! Let's add a way of going between them: humans and droids
both have friends. But humans can be friends with both humans and droids. How do
we refer to either a human or a droid?
If we look, we note that there's common functionality between humans and droids;
they both have IDs, names, and episodes in which they appear. So we'll add an
interface, `Character`, and make both `Human` and `Droid` implement it. Once we
have that, we can add the `friends` field, that returns a list of `Character`s.
Our type system so far is:
```graphql
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
interface Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
}
type Human implements Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Droid implements Character {
id: String
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
```
One question we might ask, though, is whether any of those fields can return
`null`. By default, `null` is a permitted value for any type in GraphQL, since
fetching data to fulfill a GraphQL query often requires talking to different
services that may or may not be available. However, if the type system can
guarantee that a type is never null, then we can mark it as Non Null in the type
system. We indicate that in our shorthand by adding an "!" after the type. We
can update our type system to note that the `id` is never null.
Note that while in our current implementation, we can guarantee that more fields
are non-null (since our current implementation has hard-coded data), we didn't
mark them as non-null. One can imagine we would eventually replace our hardcoded
data with a backend service, which might not be perfectly reliable; by leaving
these fields as nullable, we allow ourselves the flexibility to eventually
return null to indicate a backend error, while also telling the client that the
error occurred.
```graphql
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
interface Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
}
type Human implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
homePlanet: String
}
type Droid implements Character {
id: String!
name: String
friends: [Character]
appearsIn: [Episode]
primaryFunction: String
}
```
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
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:
```graphql
type Query {
hero(episode: Episode): Character
human(id: String!): Human
droid(id: String!): Droid
}
```
In this example, there are three top-level operations that can be done on our
schema:
- `hero` returns the `Character` who is the hero of the Star Wars trilogy; it
takes an optional argument that allows us to fetch the hero of a specific
episode instead.
- `human` accepts a non-null string as a query argument, a human's ID, and
returns the human with that ID.
- `droid` does the same for droids.
These fields demonstrate another feature of the type system, the ability for a
field to specify arguments that configure their behavior.
When we package the whole type system together, defining the `Query` type above
as our entry point for queries, this creates a GraphQL Schema.
This example just scratched the surface of the type system. The specification
goes into more detail about this topic in the "Type System" section, and the
[type](https://github.com/graphql/graphql-js/blob/main/src/type) directory in
GraphQL.js contains code implementing a specification-compliant GraphQL type
system.
### Query Syntax
GraphQL queries declaratively describe what data the issuer wishes to fetch from
whoever is fulfilling the GraphQL query.
For our Star Wars example, the
[starWarsQueryTests.js](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsQuery-test.ts)
file in the GraphQL.js repository contains a number of queries and responses.
That file is a test file that uses the schema discussed above and a set of
sample data, located in
[starWarsData.js](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsData.ts).
This test file can be run to exercise the reference implementation.
An example query on the above schema would be:
```graphql
query HeroNameQuery {
hero {
name
}
}
```
The initial line, `query HeroNameQuery`, defines a query with the operation name
`HeroNameQuery` that starts with the schema's root query type; in this case,
`Query`. As defined above, `Query` has a `hero` field that returns a
`Character`, so we'll query for that. `Character` then has a `name` field that
returns a `String`, so we query for that, completing our query. The result of
this query would then be:
```json
{
"hero": {
"name": "R2-D2"
}
}
```
Specifying the `query` keyword and an operation name is only required when a
GraphQL document defines multiple operations. We therefore could have written
the previous query with the query shorthand:
```graphql
{
hero {
name
}
}
```
Assuming that the backing data for the GraphQL server identified R2-D2 as the
hero. The response continues to vary based on the request; if we asked for
R2-D2's ID and friends with this query:
```graphql
query HeroNameAndFriendsQuery {
hero {
id
name
friends {
id
name
}
}
}
```
then we'll get back a response like this:
```json
{
"hero": {
"id": "2001",
"name": "R2-D2",
"friends": [
{
"id": "1000",
"name": "Luke Skywalker"
},
{
"id": "1002",
"name": "Han Solo"
},
{
"id": "1003",
"name": "Leia Organa"
}
]
}
}
```
One of the key aspects of GraphQL is its ability to nest queries. In the above
query, we asked for R2-D2's friends, but we can ask for more information about
each of those objects. So let's construct a query that asks for R2-D2's friends,
gets their name and episode appearances, then asks for each of _their_ friends.
```graphql
query NestedQuery {
hero {
name
friends {
name
appearsIn
friends {
name
}
}
}
}
```
which will give us the nested response
```json
{
"hero": {
"name": "R2-D2",
"friends": [
{
"name": "Luke Skywalker",
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
"friends": [
{ "name": "Han Solo" },
{ "name": "Leia Organa" },
{ "name": "C-3PO" },
{ "name": "R2-D2" }
]
},
{
"name": "Han Solo",
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Leia Organa" },
{ "name": "R2-D2" }
]
},
{
"name": "Leia Organa",
"appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
"friends": [
{ "name": "Luke Skywalker" },
{ "name": "Han Solo" },
{ "name": "C-3PO" },
{ "name": "R2-D2" }
]
}
]
}
}
```
The `Query` type above defined a way to fetch a human given their ID. We can use
it by hard-coding the ID in the query:
```graphql
query FetchLukeQuery {
human(id: "1000") {
name
}
}
```
to get
```json
{
"human": {
"name": "Luke Skywalker"
}
}
```
Alternately, we could have defined the query to have a query parameter:
```graphql
query FetchSomeIDQuery($someId: String!) {
human(id: $someId) {
name
}
}
```
This query is now parameterized by `$someId`; to run it, we must provide that
ID. If we ran it with `$someId` set to "1000", we would get Luke; set to "1002",
we would get Han. If we passed an invalid ID here, we would get `null` back for
the `human`, indicating that no such object exists.
Notice that the key in the response is the name of the field, by default. It is
sometimes useful to change this key, for clarity or to avoid key collisions when
fetching the same field with different arguments.
We can do that with field aliases, as demonstrated in this query:
```graphql
query FetchLukeAliased {
luke: human(id: "1000") {
name
}
}
```
We aliased the result of the `human` field to the key `luke`. Now the response
is:
```json
{
"luke": {
"name": "Luke Skywalker"
}
}
```
Notice the key is "luke" and not "human", as it was in our previous example
where we did not use the alias.
This is particularly useful if we want to use the same field twice with
different arguments, as in the following query:
```graphql
query FetchLukeAndLeiaAliased {
luke: human(id: "1000") {
name
}
leia: human(id: "1003") {
name
}
}
```
We aliased the result of the first `human` field to the key `luke`, and the
second to `leia`. So the result will be:
```json
{
"luke": {
"name": "Luke Skywalker"
},
"leia": {
"name": "Leia Organa"
}
}
```
Now imagine we wanted to ask for Luke and Leia's home planets. We could do so
with this query:
```graphql
query DuplicateFields {
luke: human(id: "1000") {
name
homePlanet
}
leia: human(id: "1003") {
name
homePlanet
}
}
```
but we can already see that this could get unwieldy, since we have to add new
fields to both parts of the query. Instead, we can extract out the common fields
into a fragment, and include the fragment in the query, like this:
```graphql
query UseFragment {
luke: human(id: "1000") {
...HumanFragment
}
leia: human(id: "1003") {
...HumanFragment
}
}
fragment HumanFragment on Human {
name
homePlanet
}
```
Both of those queries give this result:
```json
{
"luke": {
"name": "Luke Skywalker",
"homePlanet": "Tatooine"
},
"leia": {
"name": "Leia Organa",
"homePlanet": "Alderaan"
}
}
```
The `UseFragment` and `DuplicateFields` queries will both get the same result,
but `UseFragment` is less verbose; if we wanted to add more fields, we could add
it to the common fragment rather than copying it into multiple places.
We defined the type system above, so we know the type of each object in the
output; the query can ask for that type using the special field `__typename`,
defined on every object.
```graphql
query CheckTypeOfR2 {
hero {
__typename
name
}
}
```
Since R2-D2 is a droid, this will return
```json
{
"hero": {
"__typename": "Droid",
"name": "R2-D2"
}
}
```
This was particularly useful because `hero` was defined to return a `Character`,
which is an interface; we might want to know what concrete type was actually
returned. If we instead asked for the hero of Episode V:
```graphql
query CheckTypeOfLuke {
hero(episode: EMPIRE) {
__typename
name
}
}
```
We would find that it was Luke, who is a Human:
```json
{
"hero": {
"__typename": "Human",
"name": "Luke Skywalker"
}
}
```
As with the type system, this example just scratched the surface of the query
language. The specification goes into more detail about this topic in the
"Language" section, and the
[language](https://github.com/graphql/graphql-js/blob/main/src/language)
directory in GraphQL.js contains code implementing a specification-compliant
GraphQL query language parser and lexer.
### Validation
By using the type system, it can be predetermined whether a GraphQL query is
valid or not. This allows servers and clients to effectively inform developers
when an invalid query has been created, without having to rely on runtime
checks.
For our Star Wars example, the file
[starWarsValidationTests.js](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsValidation-test.ts)
contains a number of demonstrations of invalid operations, and is a test file
that can be run to exercise the reference implementation's validator.
To start, let's take a complex valid query. This is the `NestedQuery` example
from the above section, but with the duplicated fields factored out into a
fragment:
```graphql
query NestedQueryWithFragment {
hero {
...NameAndAppearances
friends {
...NameAndAppearances
friends {
...NameAndAppearances
}
}
}
}
fragment NameAndAppearances on Character {
name
appearsIn
}
```
And this query is valid. Let's take a look at some invalid queries!
When we query for fields, we have to query for a field that exists on the given
type. So as `hero` returns a `Character`, we have to query for a field on
`Character`. That type does not have a `favoriteSpaceship` field, so this query:
```graphql
# INVALID: favoriteSpaceship does not exist on Character
query HeroSpaceshipQuery {
hero {
favoriteSpaceship
}
}
```
is invalid.
Whenever we query for a field and it returns something other than a scalar or an
enum, we need to specify what data we want to get back from the field. Hero
returns a `Character`, and we've been requesting fields like `name` and
`appearsIn` on it; if we omit that, the query will not be valid:
```graphql
# INVALID: hero is not a scalar, so fields are needed
query HeroNoFieldsQuery {
hero
}
```
Similarly, if a field is a scalar, it doesn't make sense to query for additional
fields on it, and doing so will make the query invalid:
```graphql
# INVALID: name is a scalar, so fields are not permitted
query HeroFieldsOnScalarQuery {
hero {
name {
firstCharacterOfName
}
}
}
```
Earlier, it was noted that a query can only query for fields on the type in
question; when we query for `hero` which returns a `Character`, we can only
query for fields that exist on `Character`. What happens if we want to query for
R2-D2s primary function, though?
```graphql
# INVALID: primaryFunction does not exist on Character
query DroidFieldOnCharacter {
hero {
name
primaryFunction
}
}
```
That query is invalid, because `primaryFunction` is not a field on `Character`.
We want some way of indicating that we wish to fetch `primaryFunction` if the
`Character` is a `Droid`, and to ignore that field otherwise. We can use the
fragments we introduced earlier to do this. By setting up a fragment defined on
`Droid` and including it, we ensure that we only query for `primaryFunction`
where it is defined.
```graphql
query DroidFieldInFragment {
hero {
name
...DroidFields
}
}
fragment DroidFields on Droid {
primaryFunction
}
```
This query is valid, but it's a bit verbose; named fragments were valuable above
when we used them multiple times, but we're only using this one once. Instead of
using a named fragment, we can use an inline fragment; this still allows us to
indicate the type we are querying on, but without naming a separate fragment:
```graphql
query DroidFieldInInlineFragment {
hero {
name
... on Droid {
primaryFunction
}
}
}
```
This has just scratched the surface of the validation system; there are a number
of validation rules in place to ensure that a GraphQL query is semantically
meaningful. The specification goes into more detail about this topic in the
"Validation" section, and the
[validation](https://github.com/graphql/graphql-js/blob/main/src/validation)
directory in GraphQL.js contains code implementing a specification-compliant
GraphQL validator.
### Introspection
It's often useful to ask a GraphQL schema for information about what queries it
supports. GraphQL allows us to do so using the introspection system!
For our Star Wars example, the file
[starWarsIntrospectionTests.js](https://github.com/graphql/graphql-js/blob/main/src/__tests__/starWarsIntrospection-test.ts)
contains a number of queries demonstrating the introspection system, and is a
test file that can be run to exercise the reference implementation's
introspection system.
We designed the type system, so we know what types are available, but if we
didn't, we can ask GraphQL, by querying the `__schema` field, always available
on the root type of a Query. Let's do so now, and ask what types are available.
```graphql
query IntrospectionTypeQuery {
__schema {
types {
name
}
}
}
```
and we get back:
```json
{
"__schema": {
"types": [
{
"name": "Query"
},
{
"name": "Character"
},
{
"name": "Human"
},
{
"name": "String"
},
{
"name": "Episode"
},
{
"name": "Droid"
},
{
"name": "__Schema"
},
{
"name": "__Type"
},
{
"name": "__TypeKind"
},
{
"name": "Boolean"
},
{
"name": "__Field"
},
{
"name": "__InputValue"
},
{
"name": "__EnumValue"
},
{
"name": "__Directive"
}
]
}
}
```
Wow, that's a lot of types! What are they? Let's group them:
- **Query, Character, Human, Episode, Droid** - These are the ones that we
defined in our type system.
- **String, Boolean** - These are built-in scalars that the type system
provided.
- **`__Schema`, `__Type`, `__TypeKind`, `__Field`, `__InputValue`,
`__EnumValue`, `__Directive`** - These all are preceded with a double
underscore, indicating that they are part of the introspection system.
Now, let's try and figure out a good place to start exploring what queries are
available. When we designed our type system, we specified what type all queries
would start at; let's ask the introspection system about that!
```graphql
query IntrospectionQueryTypeQuery {
__schema {
queryType {
name
}
}
}
```
and we get back:
```json
{
"__schema": {
"queryType": {
"name": "Query"
}
}
}
```
And that matches what we said in the type system section, that the `Query` type
is where we will start! Note that the naming here was just by convention; we
could have named our `Query` type anything else, and it still would have been
returned here if we had specified it as the starting type for queries. Naming it
`Query`, though, is a useful convention.
It is often useful to examine one specific type. Let's take a look at the
`Droid` type:
```graphql
query IntrospectionDroidTypeQuery {
__type(name: "Droid") {
name
}
}
```
and we get back:
```json
{
"__type": {
"name": "Droid"
}
}
```
What if we want to know more about Droid, though? For example, is it an
interface or an object?
```graphql
query IntrospectionDroidKindQuery {
__type(name: "Droid") {
name
kind
}
}
```
and we get back:
```json
{
"__type": {
"name": "Droid",
"kind": "OBJECT"
}
}
```
`kind` returns a `__TypeKind` enum, one of whose values is `OBJECT`. If we asked
about `Character` instead:
```graphql
query IntrospectionCharacterKindQuery {
__type(name: "Character") {
name
kind
}
}
```
and we get back:
```json
{
"__type": {
"name": "Character",
"kind": "INTERFACE"
}
}
```
We'd find that it is an interface.
It's useful for an object to know what fields are available, so let's ask the
introspection system about `Droid`:
```graphql
query IntrospectionDroidFieldsQuery {
__type(name: "Droid") {
name
fields {
name
type {
name
kind
}
}
}
}
```
and we get back:
```json
{
"__type": {
"name": "Droid",
"fields": [
{
"name": "id",
"type": {
"name": null,
"kind": "NON_NULL"
}
},
{
"name": "name",
"type": {
"name": "String",
"kind": "SCALAR"
}
},
{
"name": "friends",
"type": {
"name": null,
"kind": "LIST"
}
},
{
"name": "appearsIn",
"type": {
"name": null,
"kind": "LIST"
}
},
{
"name": "primaryFunction",
"type": {
"name": "String",
"kind": "SCALAR"
}
}
]
}
}
```
Those are our fields that we defined on `Droid`!
`id` looks a bit weird there, it has no name for the type. That's because it's a
"wrapper" type of kind `NON_NULL`. If we queried for `ofType` on that field's
type, we would find the `String` type there, telling us that this is a non-null
String.
Similarly, both `friends` and `appearsIn` have no name, since they are the
`LIST` wrapper type. We can query for `ofType` on those types, which will tell
us what these are lists of.
```graphql
query IntrospectionDroidWrappedFieldsQuery {
__type(name: "Droid") {
name
fields {
name
type {
name
kind
ofType {
name
kind
}
}
}
}
}
```
and we get back:
```json
{
"__type": {
"name": "Droid",
"fields": [
{
"name": "id",
"type": {
"name": null,
"kind": "NON_NULL",
"ofType": {
"name": "String",
"kind": "SCALAR"
}
}
},
{
"name": "name",
"type": {
"name": "String",
"kind": "SCALAR",
"ofType": null
}
},
{
"name": "friends",
"type": {
"name": null,
"kind": "LIST",
"ofType": {
"name": "Character",
"kind": "INTERFACE"
}
}
},
{
"name": "appearsIn",
"type": {
"name": null,
"kind": "LIST",
"ofType": {
"name": "Episode",
"kind": "ENUM"
}
}
},
{
"name": "primaryFunction",
"type": {
"name": "String",
"kind": "SCALAR",
"ofType": null
}
}
]
}
}
```
Let's end with a feature of the introspection system particularly useful for
tooling; let's ask the system for documentation!
```graphql
query IntrospectionDroidDescriptionQuery {
__type(name: "Droid") {
name
description
}
}
```
yields
```json
{
"__type": {
"name": "Droid",
"description": "A mechanical creature in the Star Wars universe."
}
}
```
So we can access the documentation about the type system using introspection,
and create documentation browsers, or rich IDE experiences.
This has just scratched the surface of the introspection system; we can query
for enum values, what interfaces a type implements, and more. We can even
introspect on the introspection system itself. The specification goes into more
detail about this topic in the "Introspection" section, and the
[introspection](https://github.com/graphql/graphql-js/blob/main/src/type/introspection.ts)
file in GraphQL.js contains code implementing a specification-compliant GraphQL
query introspection system.
### Additional Content
This README walked through the GraphQL.js reference implementation's type
system, query execution, validation, and introspection systems. There's more in
both [GraphQL.js](https://github.com/graphql/graphql-js/) and specification,
including a description and implementation for executing queries, how to format
a response, explaining how a type system maps to an underlying implementation,
and how to format a GraphQL response, as well as the grammar for GraphQL.
### Contributing to this repo
This repository is managed by EasyCLA. Project participants must sign the free
([GraphQL Specification Membership agreement](https://preview-spec-membership.graphql.org)
before making a contribution. You only need to do this one time, and it can be
signed by
[individual contributors](https://individual-spec-membership.graphql.org/) or
their [employers](https://corporate-spec-membership.graphql.org/).
To initiate the signature process please open a PR against this repo. The
EasyCLA bot will block the merge if we still need a membership agreement from
you.
You can find
[detailed information here](https://github.com/graphql/graphql-wg/tree/main/membership).
If you have issues, please email
[operations@graphql.org](mailto:operations@graphql.org).
If your company benefits from GraphQL and you would like to provide essential
financial support for the systems and people that power our community, please
also consider membership in the
[GraphQL Foundation](https://foundation.graphql.org/join).
================================================
FILE: STYLE_GUIDE.md
================================================
**This document is a work in progress.**
# GraphQL Specification Style Guide
This document outlines the styles used in the GraphQL spec to aid editorial and
consistency. The writing style portions are inspired by the AP style guide. When
making changes to the GraphQL specification, please aim to be consistent with
this style guide.
## Auto-Formatting
The GraphQL specification is formatted using the `prettier` tool, so you should
not need to think about gaps between paragraphs and titles, nor about word
wrapping - this is handled for you.
## Headings
The GraphQL specification uses two types of headings: numbered headings and
unnumbered headings. All headings should be written in Title Case (see below).
### Numbered Headings
Lines beginning with a `#` will become numbered headings in the spec-md output.
```
# H1
## H2
### H3
#### H4
##### H5
```
### Unnumbered Headings
Unnumbered headings are added to split large blocks of text up without impacting
the spec numbering system. In the output are styled similarly to an H4. An
unnumbered heading is a line on its own that is bolded:
```md
\*\*This Is an Example of an Unnumbered Heading\*\*
```
### Title Case
Title case is used for headings. Every word in a heading (including words after
hyphens) should be capitalized, with the following exceptions:
- articles: a, an, the
- conjunctions under 4 letters in length: for, and, nor, but, or, yet, so, as,
if
- prepositions under 4 letters in length: in, at, to, on, off, of, for, vs., per
- directive names and type names are unchanged: @include, @specifiedBy,
\_\_EnumValue, \_\_Schema
All elements in hyphenated words follow the same rules, e.g. headings may
contain `Non-Null`, `Context-Free`, `Built-in` (`in` is a preposition, so is not
capitalized).
## Algorithms
A named algorithm definition starts with the name of the algorithm in
`PascalCase`, an open parenthesis, a comma-and-space separated list of
arguments, a close parenthesis and then a colon. It is followed by a blank
newline and a list of steps in the algorithm which may be numbered or bulleted.
Each step in an algorithm should either end in a colon (`:`) with an indented
step on the next line, or a fullstop (`.`). (A step after a step ending in a
full stop may or may not be indented, use your discretion.)
Indentation in algorithms is significant.
Every step in an algorithm should start with a capital letter.
```
MyAlgorithm(argOne, argTwo):
- Let {something} be {true}.
- For each {arg} in {argOne}:
- If {arg} is greater than {argTwo}:
- Let {something} be {false}.
- Otherwise if {arg} is less than {argTwo}:
- Let {something} be {true}.
- Return {something}.
```
## Definitions
For important terms, use
[Spec Markdown definition paragraphs](https://spec-md.com/#sec-Definition-Paragraph).
Definition paragraphs start with `::` and add the matching italicized term to
the [specification index](https://spec.graphql.org/draft/#index), making it easy
to reference them.
## Tone of Voice
The GraphQL specification is a reference document and should use neutral and
descriptive tone of voice.
**Favor the present tense**
The present tense is usually clearer and shorter:
✅ Present: The client then sends a request to the server.
❌ Future: The client will then send a request to the server.
**Write in the third person**
The specification should avoid the first person (“we,” “our”) and instead use
the third person or passive constructions when necessary. For example:
✅ “The server validates the request against the schema.”
❌ “We validate the request against the schema.”
**Use RFC 2119 keywords**
The specification should use the normative keywords defined in
[RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) (**MUST**, **MUST NOT**,
**SHOULD**, **SHOULD NOT**, **MAY**). However, in the context of a sentence
these words should be lower-cased (e.g., “must,” “should,” “may”) in context of
a sentence. This avoids unnecessary visual emphasis while preserving normative
meaning.
✅ “A query must contain a single root operation type.”
❌ “A query MUST contain a single root operation type.”
**Avoid unnecessary hyphenation**
Only use hypenated compound words when either commonly used elsewhere in english
or technical writing. Otherwise prefer separate words or a non-hyphenated
compound word, whichever is most commonly accepted.
✅ User defined shorthand words are separated by whitespace
❌ User-defined short-hand words are separated by white-space
================================================
FILE: build.sh
================================================
#!/bin/bash -e
# This script publishes the GraphQL specification document to the web.
# Determine if this is a tagged release
GITTAG=$(git tag --points-at HEAD)
# Build the specification draft document
echo "Building spec draft"
mkdir -p public/draft
spec-md --metadata spec/metadata.json --githubSource "https://github.com/graphql/graphql-spec/blame/main/" spec/GraphQL.md > public/draft/index.html
# If this is a tagged commit, also build the release document
if [ -n "$GITTAG" ]; then
echo "Building spec release $GITTAG"
mkdir -p "public/$GITTAG"
spec-md --metadata spec/metadata.json --githubSource "https://github.com/graphql/graphql-spec/blame/$GITTAG/" spec/GraphQL.md > "public/$GITTAG/index.html"
fi
# Create the index file
echo "Rebuilding: / (index)"
HTML="<html>
<head>
<title>GraphQL Specification Versions</title>
<style>
body {
color: #333333;
font: 13pt/18pt Cambria, 'Palatino Linotype', Palatino, 'Liberation Serif', serif;
margin: 6rem auto 3rem;
max-width: 780px;
}
@media (min-width: 1240px) {
body {
padding-right: 300px;
}
}
a {
color: #3B5998;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1 {
font-size: 1.5em;
margin: 8rem 0 2em;
}
td {
padding-bottom: 5px;
}
td + td {
padding-left: 2ch;
}
</style>
</head>
<body>
<h1>GraphQL</h1>
<table>"
# Include latest draft
GITDATE=$(git show -s --format=%cd --date=format:"%a, %b %-d, %Y" HEAD)
HTML="$HTML
<tr>
<td><em>Prerelease</em></td>
<td><a href=\"./draft\" keep-hash>Working Draft</a></td>
<td>$GITDATE</td>
<td></td>
</tr>"
GITHUB_RELEASES="https://github.com/graphql/graphql-spec/releases/tag"
for GITTAG in $(git tag -l --sort='-*committerdate') ; do
VERSIONYEAR=${GITTAG: -4}
TAGTITLE="${GITTAG%$VERSIONYEAR} $VERSIONYEAR"
TAGGEDCOMMIT=$(git rev-list -1 "$GITTAG")
GITDATE=$(git show -s --format=%cd --date=format:"%a, %b %-d, %Y" $TAGGEDCOMMIT)
HTML="$HTML
<tr>"
[ -z $HAS_LATEST_RELEASE ] && HTML="$HTML
<td><em>Latest Release</em></td>" || HTML="$HTML
<td></td>"
HAS_LATEST_RELEASE=1
HTML="$HTML
<td><a href=\"./$GITTAG\" keep-hash>$TAGTITLE</a></td>
<td>$GITDATE</td>
<td><a href=\"$GITHUB_RELEASES/$GITTAG\">Release Notes</a></td>
</tr>"
done
HTML="$HTML
</table>
<script>
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
if (links[i].hasAttribute('keep-hash')) {
links[i].href += location.hash;
links[i].removeAttribute('keep-hash');
}
}
</script>
</body>
</html>"
echo $HTML > "public/index.html"
================================================
FILE: changelogs/October2021.md
================================================
# October2021 Changelog
This describes the set of changes since the last edition of the GraphQL
specification, [June2018](https://spec.graphql.org/June2018/). It's intended to
ease the review of changes since the last edition for reviewers or curious
readers, but is not normative. Please read the
[specification document](https://spec.graphql.org/October2021/) itself for full detail
and context.
## Authors
While many have participated in the design and review RFC process, this is the
set of authors and RFC champions who have committed directly to the
specification text in this edition:
| Author |
| ------------------------------- |
| [ab-pm] |
| [Andreas Marek] |
| [Antoine Boyer] |
| [António Nuno Monteiro] |
| [Arun Ponniah Sethuramalingam] |
| [Benedikt Franke] |
| [Benjie Gillam] |
| [Brian Warner] |
| [Chris Brown] |
| [David Glasser] |
| [dugenkui] |
| [Edwin Shin] |
| [Evan Huus] |
| [Grant Wu] |
| [Görcsös Zoltán] |
| [Ivan Goncharov] |
| [Ivan Maximov] |
| [James Scott] |
| [Jamie Schouten] |
| [Joe Duarte] |
| [Kei Kamikawa] |
| [Lee Byron] |
| [Loren Sands-Ramshaw] |
| [Marais Rossouw] |
| [Marc Knaup] |
| [Martin Bonnin] |
| [Matt Farmer] |
| [Matt Mahoney] |
| [Michael Joseph Rosenthal] |
| [Mike Marcacci] |
| [Matthias Prechtl] |
| [Pascal Senn] |
| [Sebastian Redl] |
| [Tejas Kumar] |
| [Oleg Ilyenko] |
[ab-pm]: https://github.com/ab-pm
[Andreas Marek]: https://github.com/andimarek
[Antoine Boyer]: https://github.com/tinnou
[António Nuno Monteiro]: https://github.com/anmonteiro
[Arun Ponniah Sethuramalingam]: https://github.com/saponniah
[Benedikt Franke]: https://github.com/spawnia
[Benjie Gillam]: https://github.com/benjie
[Brian Warner]: https://github.com/brianwarner
[Chris Brown]: https://github.com/ccbrown
[David Glasser]: https://github.com/glasser
[dugenkui]: https://github.com/dugenkui03
[Edwin Shin]: https://github.com/eddies
[Evan Huus]: https://github.com/eapache
[Grant Wu]: https://github.com/grantwwu
[Görcsös Zoltán]: https://github.com/zgorcsos
[Ivan Goncharov]: https://github.com/IvanGoncharov
[Ivan Maximov]: https://github.com/sungam3r
[James Scott]: https://github.com/scottydocs
[Jamie Schouten]: https://github.com/maantje
[Joe Duarte]: https://github.com/JoeUX
[Kei Kamikawa]: https://github.com/Code-Hex
[Lee Byron]: https://github.com/leebyron
[Loren Sands-Ramshaw]: https://github.com/lorensr
[Marais Rossouw]: https://github.com/maraisr
[Marc Knaup]: https://github.com/fluidsonic
[Martin Bonnin]: https://github.com/martinbonnin
[Matt Farmer]: https://github.com/m14t
[Matt Mahoney]: https://github.com/mjmahone
[Michael Joseph Rosenthal]: https://github.com/micimize
[Mike Marcacci]: https://github.com/mike-marcacci
[Matthias Prechtl]: https://github.com/matprec
[Pascal Senn]: https://github.com/PascalSenn
[Sebastian Redl]: https://github.com/CornedBee
[Tejas Kumar]: https://github.com/TejasQ
[Oleg Ilyenko]: https://github.com/OlegIlyenko
Generated with:
```sh
git log June2018..HEAD --format="%an <%ae>%x0A%(trailers:key=Co-authored-by,valueonly)" -- spec | sort -uf
```
## Changes
Listed in reverse-chronological order (latest commit on top).
| Hash | Change | Authors |
| ---- | ------ | ------- |
| [ae1bab6](https://github.com/graphql/graphql-spec/commit/ae1bab6ff27cc331fc17c10af14ddd6b01512bf9) | Fix typo in Handling Field Errors (#876) | Antoine Boyer <antoineb19@gmail.com>
| [fdeb37d](https://github.com/graphql/graphql-spec/commit/fdeb37d4c9528c44c3834913944880dce9f4e8bd) | Updated legal copy (#869) | [Lee Byron], [Brian Warner]
| [50bbaa8](https://github.com/graphql/graphql-spec/commit/50bbaa8bb2503ef9b3c3477d53b266c9e8205a31) | Editorial: Improve Introspection section (#857) | [Lee Byron], [Ivan Maximov], [Benjie Gillam]
| [debcdc3](https://github.com/graphql/graphql-spec/commit/debcdc381b6173adbb89a800fd2a0009a3df8568) | Improve clarity of built-in directives (#633) | [Ivan Maximov], [Lee Byron]
| [5b7b9f6](https://github.com/graphql/graphql-spec/commit/5b7b9f6415ec9861032ced3f061d6fab1406f376) | Add spellcheck to test suite (#858) | [Lee Byron]
| [086bb1f](https://github.com/graphql/graphql-spec/commit/086bb1f1a7f273b6d0787de525f1c23742374ae0) | Editorial: Define 'Schema Specification URL' (#856) | [Lee Byron]
| [40d025c](https://github.com/graphql/graphql-spec/commit/40d025ce5cb681454c0f6455c4d97e38313616d2) | fixed introspection field "specifiedBy" to "specifiedByURL" (#848) | [Kei Kamikawa], [Lee Byron]
| [61c50f2](https://github.com/graphql/graphql-spec/commit/61c50f28cb247539e4da930b5553d25ac3d8c792) | clarify that utf-8 is just a possible encoding of strings (#684) | [Andreas Marek], [Lee Byron]
| [d4777b4](https://github.com/graphql/graphql-spec/commit/d4777b428030347300f98873b5a760b5e29ae726) | Editorial: StringValue (#854) | [Lee Byron]
| [413b689](https://github.com/graphql/graphql-spec/commit/413b68974ef86b6cc8a9272bbc8360762eee3479) | RFC: __typename is not valid at subscription root (#776) | [Benjie Gillam], [Lee Byron]
| [9bb7b77](https://github.com/graphql/graphql-spec/commit/9bb7b777d0a5de26d94bb0e2993fdd4e22c13443) | Fix: Syntax highlighting in example (#851) | [Lee Byron]
| [c6eb911](https://github.com/graphql/graphql-spec/commit/c6eb91110f6f80550f8cac1c69de1c7808b93a21) | make clear that some String escape sequences are optional (#686) | [Andreas Marek], [Lee Byron]
| [044d1d4](https://github.com/graphql/graphql-spec/commit/044d1d459d5ed289a66422cc3a996a9265fe8efa) | Clarity in Section 3 (#847) | [Ivan Maximov]
| [a16d249](https://github.com/graphql/graphql-spec/commit/a16d2493f72020f63f3e689d61420c35944c953c) | State that built-in mandatory directives must be omitted (#816) | [Marais Rossouw], [Lee Byron]
| [d4a865a](https://github.com/graphql/graphql-spec/commit/d4a865adada9c78924cf29e1bc86d6ff6bcc5f15) | [RFC] Custom Scalar Specification URLs (#649) | [Evan Huus], [Matt Farmer], [Lee Byron]
| [9ec15e3](https://github.com/graphql/graphql-spec/commit/9ec15e365933caff4894aa640ac4c55f9f78e2de) | Spec edits to reduce "query ambiguity" (#777) | [Benjie Gillam], [Lee Byron]
| [f474e66](https://github.com/graphql/graphql-spec/commit/f474e666d6698f6fd061fafad862b977834a3d5b) | Editorial: Clarify meta-fields in introspection (#844) | [Lee Byron], [Benjie Gillam]
| [f8b75d3](https://github.com/graphql/graphql-spec/commit/f8b75d30970c75007f4418bf3e79112d65c2f187) | Editorial: Clarify document grammar rules (#840) | [Lee Byron]
| [0062610](https://github.com/graphql/graphql-spec/commit/0062610494be356b033b933023829fdbc7149a96) | Add CoerceResult() (#836) | [Lee Byron]
| [792671b](https://github.com/graphql/graphql-spec/commit/792671bcfc3d451514213b5f57d0f3dbe9068a9b) | __Type represents all types in the system (#775) | [Benjie Gillam], [Lee Byron]
| [d616285](https://github.com/graphql/graphql-spec/commit/d616285dad370ca4cf126482052e313a24249e1e) | Avoid parse ambiguity on type extensions (#598) | [Lee Byron]
| [adee896](https://github.com/graphql/graphql-spec/commit/adee896e83a01ba065e13df360d61eea225f2b8b) | Update 'Field Collection' explanation (#765) | [dugenkui]
| [c43d2f7](https://github.com/graphql/graphql-spec/commit/c43d2f7c8e706442662ccf95e6b7eaaeeab4b878) | Editorial: Clarify field aliases (#843) | [Lee Byron]
| [29bcc26](https://github.com/graphql/graphql-spec/commit/29bcc26766d7f62560bb5d760b39b14bc80063c4) | Editorial: Refine design principles (#839) | [Lee Byron]
| [567e05c](https://github.com/graphql/graphql-spec/commit/567e05cfa5fbe1405c652c5db0b4b65eca431cb1) | Editorial: Query shorthand (#841) | [Lee Byron]
| [2c2cea7](https://github.com/graphql/graphql-spec/commit/2c2cea7327fe8c01a819f7bf9ea9c9454e4946af) | Editorial: root types (#842) | [Lee Byron]
| [080c8b6](https://github.com/graphql/graphql-spec/commit/080c8b669967ccaa5021b9b5b1278807cbfe9c7a) | Editorial: clarify input object introspection (#838) | [Lee Byron]
| [9cb9a4b](https://github.com/graphql/graphql-spec/commit/9cb9a4b25ea975b4affbea6676cf857f8eb43967) | Replace 'query error' with 'request error' (#803) | [Benjie Gillam], [Lee Byron]
| [6dbef35](https://github.com/graphql/graphql-spec/commit/6dbef35869abbc10d7b3e3aef073ed0ebd1bf52c) | Clarify that Float does not include NaN or infinity (#780) | [David Glasser], [Lee Byron]
| [b47598f](https://github.com/graphql/graphql-spec/commit/b47598f49264d7018ef2c07e2dfc21b3e0503420) | Prettier pre-work: formatting tweaks (#832) | [Benjie Gillam], [Lee Byron]
| [d716d84](https://github.com/graphql/graphql-spec/commit/d716d84263a428c3e7f45962a2ed66a5e063d5d9) | Rename references from master to main (#835) | [Lee Byron]
| [f331650](https://github.com/graphql/graphql-spec/commit/f3316502285e46d7b9bea17e895ce79bfcb771e9) | Clarify how lexical tokens are separated (#748) | [Joe Duarte]
| [7546566](https://github.com/graphql/graphql-spec/commit/7546566bc8a9b3992e87c0a2656dab85319b3264) | fix spelling (#834) | [Lee Byron]
| [bed0a19](https://github.com/graphql/graphql-spec/commit/bed0a193436af5e3fc89b9a21a90debf7f5663a7) | Formatting: use markdown lists in 'one of' lists (#726) | [Benjie Gillam]
| [d24252b](https://github.com/graphql/graphql-spec/commit/d24252b82637a1deab3c3b8b07ce6bb3b3fda331) | Add definition of selectionSet to CreateSourceEventStream (#828) | [Benjie Gillam]
| [83b638f](https://github.com/graphql/graphql-spec/commit/83b638f0ec93cebf4d85997e3b49479a56aa051a) | Renumber list items (#824) | [Benjie Gillam]
| [d248f55](https://github.com/graphql/graphql-spec/commit/d248f551bd84042cfba1b48b95848f06dee36ea8) | Editorial: Clean trailing whitespace (#813) | [Lee Byron]
| [eb86ed9](https://github.com/graphql/graphql-spec/commit/eb86ed92bd89b6d58f25d39e6c6e8cb82620b8c9) | Disallow non-breakable chains of circular references in Input Objects (#701) | [Benedikt Franke], [Lee Byron]
| [c83baf6](https://github.com/graphql/graphql-spec/commit/c83baf6efb3abb0faeb55d118324704f3ce2c1f2) | Editorial: s/server/service (#811) | [Lee Byron]
| [d3ea511](https://github.com/graphql/graphql-spec/commit/d3ea51147c2c00c4da21cf0b624bf055dd45a02d) | Add missing VARIABLE DEFINITION (#761) | [dugenkui]
| [39caf61](https://github.com/graphql/graphql-spec/commit/39caf613baab565d42385a7ba2e643eaaa275e9b) | Clarify that __typename may be queried on unions (#756) | [David Glasser]
| [657bc69](https://github.com/graphql/graphql-spec/commit/657bc69cc834a66350ebaaa68263d6fad716f1b5) | Minor grammar fixes (#728) | [Loren Sands-Ramshaw]
| [41dc593](https://github.com/graphql/graphql-spec/commit/41dc593687768af447b70ee82bd7d92f5f7d7e82) | Add explicit example to allow nesting lists within lists (#755) | [Benedikt Franke]
| [73fc593](https://github.com/graphql/graphql-spec/commit/73fc59385f5bcbc6bec4c011eedf18aff1e127b7) | Make 'Field Selections' header stable (#773) | [Benjie Gillam]
| [abed779](https://github.com/graphql/graphql-spec/commit/abed7797820657f0ecc75e04418115ff5bd33561) | Small grammar fix (#762) | [Martin Bonnin]
| [2e5aa78](https://github.com/graphql/graphql-spec/commit/2e5aa786d30fb13f2992d71d154b4320cbcec114) | fix typo (#747) | [Andreas Marek]
| [2d67b69](https://github.com/graphql/graphql-spec/commit/2d67b696256c90e0772823f73ae9e8fd60aa4e7c) | Fix typo in Input Objects (#741) | [dugenkui]
| [05d4a3b](https://github.com/graphql/graphql-spec/commit/05d4a3be4ed8bad274209c6f855d895f824949c2) | fix __Type explanation (#737) | [dugenkui]
| [c976d31](https://github.com/graphql/graphql-spec/commit/c976d31311bdcc0590c930a3da45b9b78201fb68) | Fix typo in CollectFields (#732) | [Benjie Gillam]
| [6c9e13b](https://github.com/graphql/graphql-spec/commit/6c9e13b2281b6e30a630d334fea90d389e9099cb) | [Variables] Generalize description | [Michael Joseph Rosenthal]
| [e5c31c9](https://github.com/graphql/graphql-spec/commit/e5c31c9d8c4439d06c858ec22fde7158509283bb) | Fix 'Format' / 'Formal' typo; fix another header | [Benjie Gillam]
| [0b3c0fa](https://github.com/graphql/graphql-spec/commit/0b3c0fa7b57dd6087cc7b2b31fe7af8be54d3b23) | Section headers for formal specifications | [Benjie Gillam]
| [a0de4c5](https://github.com/graphql/graphql-spec/commit/a0de4c5cc158083b98f5002d6016118c28f42557) | [Editorial] Fix example for Variable Uniqueness (#703) | [Pascal Senn]
| [2bd2d01](https://github.com/graphql/graphql-spec/commit/2bd2d0197ee2780aa7f5895a1d06f8d64f9e83dd) | [grammar] add "the " to Type Condition section (#712) | [Michael Joseph Rosenthal]
| [ef4bbca](https://github.com/graphql/graphql-spec/commit/ef4bbca9a49999947b6d3b319addc422d47fc18e) | [Editorial]: Use non-null for if variable in @skip and @include (#722) | [Loren Sands-Ramshaw]
| [02fd71f](https://github.com/graphql/graphql-spec/commit/02fd71f816139b7e040f969860778d23df288d32) | Add description to Schema (#466) | [Ivan Goncharov]
| [3b001da](https://github.com/graphql/graphql-spec/commit/3b001da015a4b55331b534327a9ad74eb2e6d744) | Grammar: Add missing ImplementsInterface to Interface rules | [Ivan Maximov]
| [8ac091a](https://github.com/graphql/graphql-spec/commit/8ac091a4e0232def801dd8dfc6da208c3e7e347f) | Update draft URL | [Lee Byron]
| [e297e92](https://github.com/graphql/graphql-spec/commit/e297e9254bc7649ee0063164d7f3395425159e26) | RFC: Allow interfaces to implement other interfaces (#373) | [Mike Marcacci], [Lee Byron]
| [97db7cd](https://github.com/graphql/graphql-spec/commit/97db7cd2bdff15c4d195141065fa2bfb41816f60) | [editorial] Fix formatting of algorithms in Validation section (#671) | [Lee Byron]
| [4d55742](https://github.com/graphql/graphql-spec/commit/4d55742ff4f9d18a722d31846bea3ea63cf7971f) | [editorial] Localized note about order of skip and include directives (#669) | [Lee Byron]
| [be33a64](https://github.com/graphql/graphql-spec/commit/be33a640a8d12eb177f7cce0c61a1fad770a3430) | [RFC] Repeatable directives (#472) | [Oleg Ilyenko], [Lee Byron], [Benedikt Franke]
| [39f7a34](https://github.com/graphql/graphql-spec/commit/39f7a34e7af99de345ca344f9e6645ed8a6bc3f7) | Improve clarity of scalar types (#597) | [Lee Byron]
| [8ada467](https://github.com/graphql/graphql-spec/commit/8ada467ed5bc3b72ccd42508f5bb56a7ef3b1328) | Fixed that `CoerceArgumentValues` refers to `variableType` (#659) | [Marc Knaup]
| [09cdaec](https://github.com/graphql/graphql-spec/commit/09cdaecf3a4d08c9c53092ce83b0dede40adcba6) | RFC: Number value literal lookahead restrictions (#601) | [Lee Byron]
| [a73cd6f](https://github.com/graphql/graphql-spec/commit/a73cd6fef02d16483cb5f9c1f7f6d81db3c46584) | Clarify lexing is greedy with lookahead restrictions. (#599) | [Lee Byron]
| [e491220](https://github.com/graphql/graphql-spec/commit/e49122000599567bea17ad6eecf50ad17fa60693) | Added missing parameter in call to CollectFields() (#658) | [Marc Knaup]
| [bce8020](https://github.com/graphql/graphql-spec/commit/bce80208054cb1aaf7b9f9f513270ba413054da3) | [RFC] Add note recommending directive names to be namespaced (#657) | [Antoine Boyer], [Lee Byron]
| [43a5826](https://github.com/graphql/graphql-spec/commit/43a58263fe69e6c016964848a8cf6eab3c69faaf) | Update copyright and URLs from Facebook to GraphQL Foundation (#637) | [Lee Byron]
| [bb95aa5](https://github.com/graphql/graphql-spec/commit/bb95aa5c4023cc3cf04fb3450f894300db77d846) | fixed #613 (#614) | [Ivan Maximov]
| [b967f46](https://github.com/graphql/graphql-spec/commit/b967f46a6d34c8ea45b85ff6b7c97cbcfdcf02c9) | remove redundant step from SameResponseShape (#602) | [Chris Brown]
| [7ca239c](https://github.com/graphql/graphql-spec/commit/7ca239c01eb7cb950d36eebc3f341fa9a9deeb4b) | "Directive order is significant" section (#470) | [Oleg Ilyenko]
| [7237443](https://github.com/graphql/graphql-spec/commit/72374434452fc05ace73d5c5d4287e047e939ae0) | Editorial: Fix reference to StringValue from Ignored (#608) | [Lee Byron]
| [5cc1424](https://github.com/graphql/graphql-spec/commit/5cc14241511d193d2ba2c7dc95b7808e088b0caa) | values of correct type grammar fix (#603) | [Chris Brown]
| [663a18b](https://github.com/graphql/graphql-spec/commit/663a18bbcda0a8686a7bb51b1699aa997a488cb1) | Grammar fix in section 3 (#605) | [ab-pm]
| [6de9b65](https://github.com/graphql/graphql-spec/commit/6de9b654e8cd559978f8cdf5dee64a06cb054e28) | fix ExecuteField usage arguments (#607) | [Chris Brown]
| [dfd7571](https://github.com/graphql/graphql-spec/commit/dfd75718042806733e779930fbcebd6b02bb2106) | Editorial: Make grammar recursion more clear (#593) | [Lee Byron]
| [a3087c2](https://github.com/graphql/graphql-spec/commit/a3087c262022adf6a767d1cf644bc5594eb4eb14) | Remove contradictory language (#535) | [Grant Wu]
| [6b19129](https://github.com/graphql/graphql-spec/commit/6b19129b984faccf97b31356c3ebdc0d16c8e6d4) | Synchronise grammar rules across the spec (#538) | [Ivan Goncharov]
| [c7bface](https://github.com/graphql/graphql-spec/commit/c7bface58bf6f58cc809f279cba1b6245de914b4) | Update spec/Section 4 -- Introspection.md (#524) | [Görcsös Zoltán]
| [69f2bd4](https://github.com/graphql/graphql-spec/commit/69f2bd4740191b1917296d55fe08e07922123c57) | Fix grammar in Section 3 -- Type System.md (#546) | [Edwin Shin]
| [a9b186a](https://github.com/graphql/graphql-spec/commit/a9b186adf178fde9eaba0db2c2abfe05bd3caad5) | Introspection: Clarify nullability of fields in `__Type` type (#536) | [Ivan Goncharov]
| [f18c922](https://github.com/graphql/graphql-spec/commit/f18c92232e7c7a17402abc8e427ab77ec7901eaa) | Fix ambiguity about optional variables in non-null args (#520) | [Lee Byron]
| [51337d6](https://github.com/graphql/graphql-spec/commit/51337d6d038b094bc9598e15674d91b80ceca315) | Add missing '&' to Punctuator production (graphql#573) (#574) | [Sebastian Redl]
| [b79c7f7](https://github.com/graphql/graphql-spec/commit/b79c7f760b039f5c924da2a40107b70ee08fc1dd) | Added missing 'a' to section on 'Descriptions' (#527) | [James Scott]
| [7133b59](https://github.com/graphql/graphql-spec/commit/7133b599a42507734ea0e983e2aa59003951a583) | Add example of negative integer coercion to ID (#480) | [Ivan Goncharov]
| [760753e](https://github.com/graphql/graphql-spec/commit/760753edc3588923b8ee8e9885dadc22e478b911) | [RFC] Allow directives on variable definitions (#510) | [Matt Mahoney]
| [1278654](https://github.com/graphql/graphql-spec/commit/1278654d9bef295c56c08c1c0f63d4056b611e89) | Editorial changes on the spec document. (#493) | [Arun Ponniah Sethuramalingam]
| [b83ca98](https://github.com/graphql/graphql-spec/commit/b83ca9802f2d23a23d4cf2385d05b12cfd83896c) | Change scheme for URLs from http to https where https is available. (#504) | [Jamie Schouten]
| [4efbbc0](https://github.com/graphql/graphql-spec/commit/4efbbc0a091448ab2914dc6e255e0f4d5026f5dd) | Correct description of directive example (#506) | [António Nuno Monteiro]
| [1884f41](https://github.com/graphql/graphql-spec/commit/1884f4140c012063c1367edce466d5d7dbf187c1) | Fix grammar (#514) | [Ivan Goncharov]
| [4a70722](https://github.com/graphql/graphql-spec/commit/4a707222431fb68bbf649aaf7350c4dcca7c9c4d) | Revert "[RFC] Allow directives on variable definitions" (#492) | [Lee Byron]
| [b7b6a0b](https://github.com/graphql/graphql-spec/commit/b7b6a0b3c898b20395d58dd6414465a208fca440) | Move to after DefaultValue, and make [Const] | [Matt Mahoney]
| [98ffe21](https://github.com/graphql/graphql-spec/commit/98ffe217ff4fef3a6d20159ac3d96820915fa955) | [RFC] Allow directives on variable definitions | [Matt Mahoney]
| [1ee42ce](https://github.com/graphql/graphql-spec/commit/1ee42ceb453c124173615f98d0c90506f2345f9d) | Change values of x, y in example 121 (#468) | [Matthias Prechtl]
| [8ee3cc7](https://github.com/graphql/graphql-spec/commit/8ee3cc72c3141568f612dac3b66b3881f023b5ef) | Update Section 6 -- Execution.md (#469) | [Tejas Kumar]
| [b095b18](https://github.com/graphql/graphql-spec/commit/b095b18ff8c2f0f11b9fd33a8fdf2d95241fff28) | Start next working draft for future release | Travis CI
Generated with:
```sh
git log June2018..HEAD --format="| [%h](https://github.com/graphql/graphql-spec/commit/%H) | %s | %an <%ae> %(trailers:key=Co-authored-by,valueonly,separator=%x20)" -- spec
```
## Diff
### spec/GraphQL.md
<details>
<summary>spec/GraphQL.md</summary>
~~~diff
@@ -1,51 +1,72 @@
-GraphQL
--------
+# GraphQL
-*June 2018 Edition*
+*October 2021 Edition*
**Introduction**
This is the specification for GraphQL, a query language and execution engine
originally created at Facebook in 2012 for describing the capabilities and
requirements of data models for client-server applications. The development of
-this open standard started in 2015.
+this open standard started in 2015. This specification was licensed under OWFa
+1.0 in 2017. The [GraphQL Foundation](https://graphql.org/foundation/) was
+formed in 2019 as a neutral focal point for organizations who support the
+GraphQL ecosystem, and the
+[GraphQL Specification Project](https://graphql.org/community/) was established
+also in 2019 as the Joint Development Foundation Projects, LLC, GraphQL Series.
+
+If your organization benefits from GraphQL, please consider
+[becoming a member](https://graphql.org/foundation/join/#graphql-foundation)
+and helping us to sustain the activities that support the health of our neutral
+ecosystem.
+
+The GraphQL Specification Project has evolved and may continue to evolve in
+future editions of this specification. Previous editions of the GraphQL
+specification can be found at permalinks that match their
+[release tag](https://github.com/graphql/graphql-spec/releases). The latest
+working draft release can be found at
+[https://spec.graphql.org/draft](https://spec.graphql.org/draft).
-GraphQL has evolved and may continue to evolve in future editions of this
-specification. Previous editions of the GraphQL specification can be found at
-permalinks that match their [release tag](https://github.com/facebook/graphql/releases).
-The latest working draft release can be found at [facebook.github.io/graphql/draft/](http://facebook.github.io/graphql/draft/).
**Copyright notice**
-Copyright © 2015-present, Facebook, Inc.
+Copyright © 2015-2018, Facebook, Inc.
-As of September 26, 2017, the following persons or entities have made this
-Specification available under the Open Web Foundation Final Specification
-Agreement (OWFa 1.0), which is available at [openwebfoundation.org](http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0).
+Copyright © 2019-present, GraphQL contributors
-* Facebook, Inc.
-
-You can review the signed copies of the Open Web Foundation Final Specification
-Agreement Version 1.0 for this specification at [github.com/facebook/graphql](https://github.com/facebook/graphql/tree/master/signed-agreements),
-which may also include additional parties to those listed above.
-
-Your use of this Specification may be subject to other third party rights.
-THIS SPECIFICATION IS PROVIDED “AS IS.” The contributors expressly disclaim any
+THESE MATERIALS ARE PROVIDED “AS IS.” The parties expressly disclaim any
warranties (express, implied, or otherwise), including implied warranties of
merchantability, non-infringement, fitness for a particular purpose, or title,
-related to the Specification. The entire risk as to implementing or otherwise
-using the Specification is assumed by the Specification implementer and user.
-IN NO EVENT WILL ANY PARTY BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY
-FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER
-FROM ANY CAUSES OF ACTION OF ANY KIND WITH RESPECT TO THIS SPECIFICATION OR ITS
-GOVERNING AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING
-NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER PARTY HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
+related to the materials. The entire risk as to implementing or otherwise using
+the materials is assumed by the implementer and user. IN NO EVENT WILL THE
+PARTIES BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES
+OF ACTION OF ANY KIND WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING
+AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR
+OTHERWISE, AND WHETHER OR NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+**Licensing**
+
+The GraphQL Specification Project is made available by the
+[Joint Development Foundation](https://www.jointdevelopment.org/). The current
+[Working Group](https://github.com/graphql/graphql-wg) charter, which includes
+the IP policy governing all working group deliverables (including specifications,
+source code, and datasets) may be found at
+[https://technical-charter.graphql.org](https://technical-charter.graphql.org).
+
+Currently, the licenses governing GraphQL Specification Project deliverables are:
+
+| Deliverable | License |
+| -------------- | ------------------------------------------------------- |
+| Specifications | [Open Web Foundation Agreement 1.0 Mode](http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0) (Patent and Copyright)
+| Source code | [MIT License](https://opensource.org/licenses/MIT)
+| Data sets | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/)
**Conformance**
A conforming implementation of GraphQL must fulfill all normative requirements.
Conformance requirements are described in this document via both
descriptive assertions and key words with clearly defined meanings.
~~~
</details>
<details>
<summary>spec/Section 1 -- Overview.md</summary>
~~~diff
@@ -21,65 +21,65 @@ Which produces the resulting data (in JSON):
{
"user": {
"name": "Mark Zuckerberg"
}
}
```
GraphQL is not a programming language capable of arbitrary computation, but is
-instead a language used to query application servers 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 servers that
-implement it. Instead, application servers take their capabilities and map them
+particular programming language or storage system for application services that
+implement it. Instead, application services take their capabilities and map them
to a uniform language, type system, and philosophy that GraphQL encodes.
This provides a unified interface friendly to product development and a powerful
platform for tool-building.
GraphQL has a number of design principles:
- * **Hierarchical**: Most product development today involves the creation and
- manipulation of view hierarchies. To achieve congruence with the structure
- of these applications, a GraphQL query itself is structured hierarchically.
- The query is shaped just like the data it returns. It is a natural
- way for clients to describe data requirements.
-
* **Product-centric**: GraphQL is unapologetically driven by the requirements
of views and the front-end engineers that write them. GraphQL starts with
their way of thinking and requirements and builds the language and runtime
necessary to enable that.
- * **Strong-typing**: Every GraphQL server defines an application-specific
- type system. Queries are executed within the context of that type system.
- Given a query, tools can ensure that the query is both syntactically
- correct and valid within the GraphQL type system before execution, i.e. at
- development time, and the server can make certain guarantees about the shape
+ * **Hierarchical**: Most product development today involves the creation and
+ manipulation of view hierarchies. To achieve congruence with the structure
+ of these applications, a GraphQL request itself is structured hierarchically.
+ The request is shaped just like the data in its response. It is a natural way
+ for clients to describe data requirements.
+
+ * **Strong-typing**: Every GraphQL service defines an application-specific
+ type system. Requests are executed within the context of that type system.
+ Given a GraphQL operation, tools can ensure that it is both syntactically
+ correct and valid within that type system before execution, i.e. at
+ development time, and the service can make certain guarantees about the shape
and nature of the response.
- * **Client-specified queries**: Through its type system, a GraphQL server
+ * **Client-specified response**: Through its type system, a GraphQL service
publishes the capabilities that its clients are allowed to consume. It is
the client that is responsible for specifying exactly how it will consume
- those published capabilities. These queries are specified at field-level
- granularity. In the majority of client-server applications written
- without GraphQL, the server determines the data returned in its various
- scripted endpoints. A GraphQL query, on the other hand, returns exactly what
- a client asks for and no more.
+ those published capabilities. These requests are specified at field-level
+ granularity. In the majority of client-server applications written without
+ GraphQL, the service determines the shape of data returned from its various
+ endpoints. A GraphQL response, on the other hand, contains exactly what a
+ client asks for and no more.
- * **Introspective**: GraphQL is introspective. A GraphQL server's type system
- must be queryable by the GraphQL language itself, as will be described in this
+ * **Introspective**: GraphQL is introspective. A GraphQL service's type system
+ can be queryable by the GraphQL language itself, as will be described in this
specification. GraphQL introspection serves as a powerful platform for
building common tools and client software libraries.
Because of these principles, GraphQL is a powerful and productive environment
for building client applications. Product developers and designers building
-applications against working GraphQL servers -- supported with quality tools --
-can quickly become productive without reading extensive documentation and with
+applications against working GraphQL services—supported with quality tools—can
+quickly become productive without reading extensive documentation and with
little or no formal training. To enable that experience, there must be those
-that build those servers and tools.
+that build those services and tools.
The following formal specification serves as a reference for those builders.
It describes the language and its grammar, the type system and the
introspection system used to query it, and the execution and validation engines
with the algorithms to power them. The goal of this specification is to provide
a foundation and framework for an ecosystem of GraphQL tools, client libraries,
-and server implementations -- spanning both organizations and platforms -- that
+and service implementations—spanning both organizations and platforms—that
has yet to be built. We look forward to working with the community
in order to do that.
~~~
</details>
<details>
<summary>spec/Section 2 -- Language.md</summary>
~~~diff
@@ -1,43 +1,78 @@
# Language
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
-grammar which matches patterns of source characters (defined by a
-double-colon `::`).
+grammar which matches patterns of source characters. In this document, syntactic
+grammar productions are distinguished with a colon `:` while lexical grammar
+productions are distinguished with a double-colon `::`.
-Note: See [Appendix A](#sec-Appendix-Notation-Conventions) for more details about the definition of lexical and syntactic grammar and other notational conventions
-used in this document.
+The source text of a GraphQL document must be a sequence of {SourceCharacter}.
+The character sequence must be described by a sequence of {Token} and {Ignored}
+lexical grammars. The lexical token sequence, omitting {Ignored}, must be
+described by a single {Document} syntactic grammar.
+
+Note: See [Appendix A](#sec-Appendix-Notation-Conventions) for more information
+about the lexical and syntactic grammar and other notational conventions used
+throughout this document.
+
+**Lexical Analysis & Syntactic Parse**
+
+The source text of a GraphQL document is first converted into a sequence of
+lexical tokens, {Token}, and ignored tokens, {Ignored}. The source text is
+scanned from left to right, repeatedly taking the next possible sequence of
+code-points allowed by the lexical grammar productions as the next token. This
+sequence of lexical tokens are then scanned from left to right to produce an
+abstract syntax tree (AST) according to the {Document} syntactical grammar.
+
+Lexical grammar productions in this document use *lookahead restrictions* to
+remove ambiguity and ensure a single valid lexical analysis. A lexical token is
+only valid if not followed by a character in its lookahead restriction.
+
+For example, an {IntValue} has the restriction {[lookahead != Digit]}, so cannot
+be followed by a {Digit}. Because of this, the sequence {`123`} cannot represent
+the tokens ({`12`}, {`3`}) since {`12`} is followed by the {Digit} {`3`} and
+so must only represent a single token. Use {WhiteSpace} or other {Ignored}
+between characters to represent multiple tokens.
+
+Note: This typically has the same behavior as a
+"[maximal munch](https://en.wikipedia.org/wiki/Maximal_munch)" longest possible
+match, however some lookahead restrictions include additional constraints.
## Source Text
-SourceCharacter :: /[\u0009\u000A\u000D\u0020-\uFFFF]/
+SourceCharacter ::
+ - "U+0009"
+ - "U+000A"
+ - "U+000D"
+ - "U+0020–U+FFFF"
GraphQL documents are expressed as a sequence of
-[Unicode](http://unicode.org/standard/standard.html) characters. However, with
+[Unicode](https://unicode.org/standard/standard.html) code points (informally
+referred to as *"characters"* through most of this specification). However, with
few exceptions, most of GraphQL is expressed only in the original non-control
ASCII range so as to be as widely compatible with as many existing tools,
languages, and serialization formats as possible and avoid display issues in
text editors and source control.
+Note: Non-ASCII Unicode characters may appear freely within {StringValue} and
+{Comment} portions of GraphQL.
+
### Unicode
UnicodeBOM :: "Byte Order Mark (U+FEFF)"
-Non-ASCII Unicode characters may freely appear within {StringValue} and
-{Comment} portions of GraphQL.
-
The "Byte Order Mark" is a special Unicode character which
may appear at the beginning of a file containing Unicode which programs may use
to determine the fact that the text stream is Unicode, what endianness the text
stream is in, and which of several Unicode encodings to interpret.
### White Space
@@ -55,158 +90,195 @@ Note: GraphQL intentionally does not consider Unicode "Zs" category characters
as white-space, avoiding misinterpretation by text editors and source
control tools.
### Line Terminators
LineTerminator ::
- "New Line (U+000A)"
- - "Carriage Return (U+000D)" [ lookahead ! "New Line (U+000A)" ]
+ - "Carriage Return (U+000D)" [lookahead != "New Line (U+000A)"]
- "Carriage Return (U+000D)" "New Line (U+000A)"
Like white space, line terminators are used to improve the legibility of source
-text, any amount may appear before or after any other token and have no
-significance to the semantic meaning of a GraphQL Document. Line
-terminators are not found within any other token.
+text and separate lexical tokens, any amount may appear before or after any
+other token and have no significance to the semantic meaning of a GraphQL
+Document. Line terminators are not found within any other token.
-Note: Any error reporting which provide the line number in the source of the
+Note: Any error reporting which provides the line number in the source of the
offending syntax should use the preceding amount of {LineTerminator} to produce
the line number.
### Comments
-Comment :: `#` CommentChar*
+Comment :: `#` CommentChar* [lookahead != CommentChar]
CommentChar :: SourceCharacter but not LineTerminator
GraphQL source documents may contain single-line comments, starting with the
{`#`} marker.
-A comment can contain any Unicode code point except {LineTerminator} so a
-comment always consists of all code points starting with the {`#`} character up
-to but not including the line terminator.
+A comment can contain any Unicode code point in {SourceCharacter} except
+{LineTerminator} so a comment always consists of all code points starting with
+the {`#`} character up to but not including the {LineTerminator} (or end of
+the source).
-Comments behave like white space and may appear after any token, or before a
-line terminator, and have no significance to the semantic meaning of a
+Comments are {Ignored} like white space and may appear after any token, or
+before a {LineTerminator}, and have no significance to the semantic meaning of a
GraphQL Document.
### Insignificant Commas
Comma :: ,
Similar to white space and line terminators, commas ({`,`}) are used to improve
the legibility of source text and separate lexical tokens but are otherwise
syntactically and semantically insignificant within GraphQL Documents.
Non-significant comma characters ensure that the absence or presence of a comma
does not meaningfully alter the interpreted syntax of the document, as this can
be a common user-error in other languages. It also allows for the stylistic use
-of either trailing commas or line-terminators as list delimiters which are both
+of either trailing commas or line terminators as list delimiters which are both
often desired for legibility and maintainability of source code.
### Lexical Tokens
Token ::
- Punctuator
- Name
- IntValue
- FloatValue
- StringValue
A GraphQL document is comprised of several kinds of indivisible lexical tokens
defined here in a lexical grammar by patterns of source Unicode characters.
+Lexical tokens may be separated by {Ignored} tokens.
-Tokens are later used as terminal symbols in a GraphQL Document
-syntactic grammars.
+Tokens are later used as terminal symbols in GraphQL syntactic grammar rules.
### Ignored Tokens
Ignored ::
- UnicodeBOM
- WhiteSpace
- LineTerminator
- Comment
- Comma
-Before and after every lexical token may be any amount of ignored tokens
-including {WhiteSpace} and {Comment}. No ignored regions of a source
-document are significant, however ignored source characters may appear within
-a lexical token in a significant way, for example a {String} may contain white
-space characters.
+{Ignored} tokens are used to improve readability and provide separation between
+lexical tokens, but are otherwise insignificant and not referenced in
+syntactical grammar productions.
-No characters are ignored while parsing a given token, as an example no
-white space characters are permitted between the characters defining a
-{FloatValue}.
+Any amount of {Ignored} may appear before and after every lexical token. No
+ignored regions of a source document are significant, however {SourceCharacter}
+which appear in {Ignored} may also appear within a lexical {Token} in a
+significant way, for example a {StringValue} may contain white space characters.
+No {Ignored} may appear *within* a {Token}, for example no white space
+characters are permitted between the characters defining a {FloatValue}.
### Punctuators
-Punctuator :: one of ! $ ( ) ... : = @ [ ] { | }
+Punctuator :: one of ! $ & ( ) ... : = @ [ ] { | }
GraphQL documents include punctuation in order to describe structure. GraphQL
is a data description language and not a programming language, therefore GraphQL
lacks the punctuation often used to describe mathematical expressions.
### Names
-Name :: /[_A-Za-z][_0-9A-Za-z]*/
+Name ::
+ - NameStart NameContinue* [lookahead != NameContinue]
+
+NameStart ::
+ - Letter
+ - `_`
+
+NameContinue ::
+ - Letter
+ - Digit
+ - `_`
+
+Letter :: one of
+ - `A` `B` `C` `D` `E` `F` `G` `H` `I` `J` `K` `L` `M`
+ - `N` `O` `P` `Q` `R` `S` `T` `U` `V` `W` `X` `Y` `Z`
+ - `a` `b` `c` `d` `e` `f` `g` `h` `i` `j` `k` `l` `m`
+ - `n` `o` `p` `q` `r` `s` `t` `u` `v` `w` `x` `y` `z`
+
+Digit :: one of
+ - `0` `1` `2` `3` `4` `5` `6` `7` `8` `9`
GraphQL Documents are full of named things: operations, fields, arguments,
types, directives, fragments, and variables. All names must follow the same
grammatical form.
Names in GraphQL are case-sensitive. That is to say `name`, `Name`, and `NAME`
all refer to different names. Underscores are significant, which means
`other_name` and `othername` are two different names.
-Names in GraphQL are limited to this <acronym>ASCII</acronym> subset of possible
-characters to support interoperation with as many other systems as possible.
+A {Name} must not be followed by a {NameContinue}. In other words, a {Name}
+token is always the longest possible valid sequence. The source characters
+{`a1`} cannot be interpreted as two tokens since {`a`} is followed by the {NameContinue} {`1`}.
+
+Note: Names in GraphQL are limited to the Latin <acronym>ASCII</acronym> subset
+of {SourceCharacter} in order to support interoperation with as many other
+systems as possible.
+
+**Reserved Names**
+
+Any {Name} within a GraphQL type system must not start with two underscores
+{"__"} unless it is part of the [introspection system](#sec-Introspection) as
+defined by this specification.
## Document
Document : Definition+
Definition :
- ExecutableDefinition
- - TypeSystemDefinition
- - TypeSystemExtension
+ - TypeSystemDefinitionOrExtension
+
+ExecutableDocument : ExecutableDefinition+
ExecutableDefinition :
- OperationDefinition
- FragmentDefinition
A GraphQL Document describes a complete file or request string operated on
by a GraphQL service or client. A document contains multiple definitions, either
executable or representative of a GraphQL type system.
-Documents are only executable by a GraphQL service if they contain an
-{OperationDefinition} and otherwise only contain {ExecutableDefinition}.
-However documents which do not contain {OperationDefinition} or do contain
-{TypeSystemDefinition} or {TypeSystemExtension} may still be parsed
-and validated to allow client tools to represent many GraphQL uses which may
-appear across many individual files.
+Documents are only executable by a GraphQL service if they are
+{ExecutableDocument} and contain at least one {OperationDefinition}. A
+Document which contains {TypeSystemDefinitionOrExtension} must not be executed;
+GraphQL execution services which receive a Document containing these should
+return a descriptive error.
-If a Document contains only one operation, that operation may be unnamed or
-represented in the shorthand form, which omits both the query keyword and
-operation name. Otherwise, if a GraphQL Document contains multiple
+GraphQL services which only seek to execute GraphQL requests and not construct
+a new GraphQL schema may choose to only permit {ExecutableDocument}.
+
+Documents which do not contain {OperationDefinition} or do contain
+{TypeSystemDefinitionOrExtension} may still be parsed and validated to allow
+client tools to represent many GraphQL uses which may appear across many
+individual files.
+
+If a Document contains only one operation, that operation may be unnamed. If
+that operation is a query without variables or directives then it may also be
+represented in the shorthand form, omitting both the {`query`} keyword as well
+as the operation name. Otherwise, if a GraphQL Document contains multiple
operations, each operation must be named. When submitting a Document with
multiple operations to a GraphQL service, the name of the desired operation to
be executed must also be provided.
-GraphQL services which only seek to provide GraphQL query execution may choose
-to only include {ExecutableDefinition} and omit the {TypeSystemDefinition} and
-{TypeSystemExtension} rules from {Definition}.
-
## Operations
OperationDefinition :
- OperationType Name? VariableDefinitions? Directives? SelectionSet
- SelectionSet
OperationType : one of `query` `mutation` `subscription`
@@ -230,19 +302,20 @@ mutation {
likeCount
}
}
}
```
**Query shorthand**
-If a document contains only one query operation, and that query defines no
-variables and contains no directives, that operation may be represented in a
-short-hand form which omits the query keyword and query name.
+If a document contains only one operation and that operation is a query which
+defines no variables and contains no directives then that operation may be
+represented in a short-hand form which omits the {`query`} keyword and operation
+name.
For example, this unnamed query operation is written via query shorthand.
```graphql example
{
field
}
```
@@ -266,18 +339,18 @@ under-fetching data.
```graphql example
{
id
firstName
lastName
}
```
-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
Field : Alias? Name Arguments? Directives? SelectionSet?
A selection set is primarily composed of fields. A field describes one discrete
piece of information available to request within a selection set.
@@ -335,17 +408,17 @@ unique identifier.
## Arguments
Arguments[Const] : ( Argument[?Const]+ )
Argument[Const] : Name : Value[?Const]
Fields are conceptually functions which return values, and occasionally accept
arguments which alter their behavior. These arguments often map directly to
-function arguments within a GraphQL server's implementation.
+function arguments within a GraphQL service's implementation.
In this example, we want to query a specific user (requested via the `id`
argument) and their profile picture of a specific `size`:
```graphql example
{
user(id: 4) {
id
@@ -367,17 +440,17 @@ Many arguments can exist for a given field:
}
```
**Arguments are unordered**
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
{
picture(width: 200, height: 100)
}
```
```graphql example
@@ -386,71 +459,68 @@ These two queries are semantically identical:
}
```
## Field Alias
Alias : Name :
-By default, the key in the response object will use the field name
-queried. However, you can define a different name by specifying an alias.
+By default a field's response key in the response object will use that field's
+name. However, you can define a different response key by specifying an alias.
In this example, we can fetch two profile pictures of different sizes and ensure
-the resulting object will not have duplicate keys:
+the resulting response object will not have duplicate keys:
```graphql example
{
user(id: 4) {
id
name
smallPic: profilePic(size: 64)
bigPic: profilePic(size: 1024)
}
}
```
-Which returns the result:
+which returns the result:
```json example
{
"user": {
"id": 4,
"name": "Mark Zuckerberg",
"smallPic": "https://cdn.site.io/pic-4-64.jpg",
"bigPic": "https://cdn.site.io/pic-4-1024.jpg"
}
}
```
-Since the top level of a query is a field, it also can be given an alias:
+The fields at the top level of an operation can also be given an alias:
```graphql example
{
zuck: user(id: 4) {
id
name
}
}
```
-Returns the result:
+which returns the result:
```json example
{
"zuck": {
"id": 4,
"name": "Mark Zuckerberg"
}
}
```
-A field's response key is its alias if an alias is provided, and it is
-otherwise the field's name.
-
## Fragments
FragmentSpread : ... FragmentName Directives?
FragmentDefinition : fragment FragmentName TypeCondition Directives? SelectionSet
FragmentName : Name but not `on`
@@ -478,17 +548,17 @@ query noFragments {
name
profilePic(size: 50)
}
}
}
```
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 {
user(id: 4) {
friends(first: 10) {
...friendFields
}
mutualFriends(first: 10) {
@@ -499,18 +569,18 @@ query withFragments {
fragment friendFields on User {
id
name
profilePic(size: 50)
}
```
-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.
For example:
```graphql example
query withNestedFragments {
user(id: 4) {
@@ -529,40 +599,40 @@ fragment friendFields on User {
...standardProfilePic
}
fragment standardProfilePic on User {
profilePic(size: 50)
}
```
-The queries `noFragments`, `withFragments`, and `withNestedFragments` all
+The operations `noFragments`, `withFragments`, and `withNestedFragments` all
produce the same response object.
### Type Conditions
TypeCondition : on NamedType
Fragments must specify the type they apply to. In this example, `friendFields`
can be used in the context of querying a `User`.
Fragments cannot be specified on any input value (scalar, enumeration, or input
object).
Fragments can be specified on object types, interfaces, and unions.
-Selections within fragments only return values when concrete type of the object
+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 {
- profiles(handles: ["zuck", "cocacola"]) {
+ profiles(handles: ["zuck", "coca-cola"]) {
handle
...userFragment
...pageFragment
}
}
fragment userFragment on User {
friends {
@@ -582,21 +652,21 @@ The `profiles` root field returns a list where each element could be a `Page` or
present and `likers` will not. Conversely when the result is a `Page`, `likers`
will be present and `friends` will not.
```json example
{
"profiles": [
{
"handle": "zuck",
- "friends": { "count" : 1234 }
+ "friends": { "count": 1234 }
},
{
- "handle": "cocacola",
- "likers": { "count" : 90234512 }
+ "handle": "coca-cola",
+ "likers": { "count": 90234512 }
}
]
}
```
### Inline Fragments
@@ -604,17 +674,17 @@ InlineFragment : ... TypeCondition? Directives? SelectionSet
Fragments can be defined inline within a selection set. This is done to
conditionally include fields based on their runtime type. This feature of
standard fragment inclusion was demonstrated in the `query FragmentTyping`
example. We could accomplish the same thing using inline fragments.
```graphql example
query inlineFragmentTyping {
- profiles(handles: ["zuck", "cocacola"]) {
+ profiles(handles: ["zuck", "coca-cola"]) {
handle
... on User {
friends {
count
}
}
... on Page {
likers {
@@ -661,98 +731,131 @@ Field and directive arguments accept input values of various literal primitives;
input values can be scalars, enumeration values, lists, or input objects.
If not defined as constant (for example, in {DefaultValue}), input values can be
specified as a variable. List and inputs objects may also contain variables (unless defined to be constant).
### Int Value
-IntValue :: IntegerPart
+IntValue :: IntegerPart [lookahead != {Digit, `.`, NameStart}]
IntegerPart ::
- NegativeSign? 0
- NegativeSign? NonZeroDigit Digit*
NegativeSign :: -
-Digit :: one of 0 1 2 3 4 5 6 7 8 9
-
NonZeroDigit :: Digit but not `0`
-An Int number is specified without a decimal point or exponent (ex. `1`).
+An {IntValue} is specified without a decimal point or exponent but may be
+negative (ex. {-123}). It must not have any leading {0}.
+
+An {IntValue} must not be followed by a {Digit}. In other words, an {IntValue}
+token is always the longest possible valid sequence. The source characters
+{12} cannot be interpreted as two tokens since {1} is followed by the {Digit}
+{2}. This also means the source {00} is invalid since it can neither be
+interpreted as a single token nor two {0} tokens.
+
+An {IntValue} must not be followed by a {`.`} or {NameStart}. If either {`.`} or
+{ExponentIndicator} follows then the token must only be interpreted as a
+possible {FloatValue}. No other {NameStart} character can follow. For example
+the sequences `0x123` and `123L` have no valid lexical representations.
### Float Value
FloatValue ::
- - IntegerPart FractionalPart
- - IntegerPart ExponentPart
- - IntegerPart FractionalPart ExponentPart
+ - IntegerPart FractionalPart ExponentPart [lookahead != {Digit, `.`, NameStart}]
+ - IntegerPart FractionalPart [lookahead != {Digit, `.`, NameStart}]
+ - IntegerPart ExponentPart [lookahead != {Digit, `.`, NameStart}]
FractionalPart :: . Digit+
ExponentPart :: ExponentIndicator Sign? Digit+
ExponentIndicator :: one of `e` `E`
Sign :: one of + -
-A Float number includes either a decimal point (ex. `1.0`) or an exponent
-(ex. `1e50`) or both (ex. `6.0221413e23`).
+A {FloatValue} includes either a decimal point (ex. {1.0}) or an exponent
+(ex. {1e50}) or both (ex. {6.0221413e23}) and may be negative. Like {IntValue},
+it also must not have any leading {0}.
+
+A {FloatValue} must not be followed by a {Digit}. In other words, a {FloatValue}
+token is always the longest possible valid sequence. The source characters
+{1.23} cannot be interpreted as two tokens since {1.2} is followed by the
+{Digit} {3}.
+
+A {FloatValue} must not be followed by a {.}. For example, the sequence {1.23.4}
+cannot be interpreted as two tokens ({1.2}, {3.4}).
+
+A {FloatValue} must not be followed by a {NameStart}. For example the sequence
+`0x1.2p3` has no valid lexical representation.
+
+Note: The numeric literals {IntValue} and {FloatValue} both restrict being
+immediately followed by a letter (or other {NameStart}) to reduce confusion
+or unexpected behavior since GraphQL only supports decimal numbers.
### Boolean Value
BooleanValue : one of `true` `false`
The two keywords `true` and `false` represent the two boolean values.
### String Value
StringValue ::
- - `"` StringCharacter* `"`
+ - `""` [lookahead != `"`]
+ - `"` StringCharacter+ `"`
- `"""` BlockStringCharacter* `"""`
StringCharacter ::
- - SourceCharacter but not `"` or \ or LineTerminator
- - \u EscapedUnicode
- - \ EscapedCharacter
+ - SourceCharacter but not `"` or `\` or LineTerminator
+ - `\u` EscapedUnicode
+ - `\` EscapedCharacter
EscapedUnicode :: /[0-9A-Fa-f]{4}/
-EscapedCharacter :: one of `"` \ `/` b f n r t
+EscapedCharacter :: one of `"` `\` `/` `b` `f` `n` `r` `t`
BlockStringCharacter ::
- SourceCharacter but not `"""` or `\"""`
- `\"""`
-Strings are sequences of characters wrapped in double-quotes (`"`). (ex.
-`"Hello World"`). White space and other otherwise-ignored characters are
+Strings are sequences of characters wrapped in quotation marks (U+0022).
+(ex. {`"Hello World"`}). White space and other otherwise-ignored characters are
significant within a string value.
-Note: Unicode characters are allowed within String value literals, however
-{SourceCharacter} must not contain some ASCII control characters so escape
-sequences must be used to represent these characters.
+The empty string {`""`} must not be followed by another {`"`} otherwise it would
+be interpreted as the beginning of a block string. As an example, the source
+{`""""""`} can only be interpreted as a single empty block string and not three
+empty strings.
+
+Non-ASCII Unicode characters are allowed within single-quoted strings.
+Since {SourceCharacter} must not contain some ASCII control characters, escape
+sequences must be used to represent these characters. The {`\`}, {`"`}
+characters also must be escaped. All other escape sequences are optional.
**Block Strings**
Block strings are sequences of characters wrapped in triple-quotes (`"""`).
White space, line terminators, quote, and backslash characters may all be
used unescaped to enable verbatim text. Characters must all be valid
{SourceCharacter}.
Since block strings represent freeform text often used in indented
positions, the string value semantics of a block string excludes uniform
indentation and blank initial and trailing lines via {BlockStringValue()}.
For example, the following operation containing a block string:
-```graphql example
+```raw graphql example
mutation {
sendEmail(message: """
Hello,
World!
Yours,
GraphQL.
""")
@@ -785,44 +888,49 @@ which makes it a little harder to read."""
```
Note: If non-printable ASCII characters are needed in a string value, a standard
quoted string with appropriate escape sequences must be used instead of a
block string.
**Semantics**
-StringValue :: `"` StringCharacter* `"`
+StringValue :: `""`
- * Return the Unicode character sequence of all {StringCharacter}
- Unicode character values (which may be an empty sequence).
+ * Return an empty sequence.
-StringCharacter :: SourceCharacter but not `"` or \ or LineTerminator
+StringValue :: `"` StringCharacter+ `"`
- * Return the character value of {SourceCharacter}.
+ * Return the sequence of all {StringCharacter} code points.
+
+StringCharacter :: SourceCharacter but not `"` or `\` or LineTerminator
+
+ * Return the code point {SourceCharacter}.
-StringCharacter :: \u EscapedUnicode
+StringCharacter :: `\u` EscapedUnicode
- * Return the character whose code unit value in the Unicode Basic Multilingual
- Plane is the 16-bit hexadecimal value {EscapedUnicode}.
+ * Let {value} be the 16-bit hexadecimal value represented by the sequence of
+ hexadecimal digits within {EscapedUnicode}.
+ * Return the code point {value}.
-StringCharacter :: \ EscapedCharacter
+StringCharacter :: `\` EscapedCharacter
- * Return the character value of {EscapedCharacter} according to the table below.
+ * Return the code point represented by {EscapedCharacter} according to the
+ table below.
-| Escaped Character | Code Unit Value | Character Name |
-| ----------------- | --------------- | ---------------------------- |
-| `"` | U+0022 | double quote |
-| `\` | U+005C | reverse solidus (back slash) |
-| `/` | U+002F | solidus (forward slash) |
-| `b` | U+0008 | backspace |
-| `f` | U+000C | form feed |
-| `n` | U+000A | line feed (new line) |
-| `r` | U+000D | carriage return |
-| `t` | U+0009 | horizontal tab |
+| Escaped Character | Code Point | Character Name |
+| ----------------- | ---------- | ---------------------------- |
+| {`"`} | U+0022 | double quote |
+| {`\`} | U+005C | reverse solidus (back slash) |
+| {`/`} | U+002F | solidus (forward slash) |
+| {`b`} | U+0008 | backspace |
+| {`f`} | U+000C | form feed |
+| {`n`} | U+000A | line feed (new line) |
+| {`r`} | U+000D | carriage return |
+| {`t`} | U+0009 | horizontal tab |
StringValue :: `"""` BlockStringCharacter* `"""`
* Let {rawValue} be the Unicode character sequence of all
{BlockStringCharacter} Unicode character values (which may be an empty
sequence).
* Return the result of {BlockStringValue(rawValue)}.
@@ -879,24 +987,24 @@ For example, these two field calls are similar, but are not identical:
```graphql example
{
field(arg: null)
field
}
```
-The first has explictly provided {null} to the argument "arg", while the second
+The first has explicitly provided {null} to the argument "arg", while the second
has implicitly not provided a value to the argument "arg". These two forms may
be interpreted differently. For example, a mutation representing deleting a
field vs not altering a field, respectively. Neither form may be used for an
input expecting a Non-Null type.
Note: The same two methods of representing the lack of a value are possible via
-variables by either providing the a variable value as {null} and not providing
+variables by either providing the variable value as {null} or not providing
a variable value at all.
### Enum Value
EnumValue : Name but not `true`, `false` or `null`
Enum values are represented as unquoted names (ex. `MOBILE_WEB`). It is
@@ -945,17 +1053,17 @@ curly-braces `{ }`. The values of an object literal may be any input value
literal or variable (ex. `{ name: "Hello world", score: 1.0 }`). We refer to
literal representation of input objects as "object literals."
**Input object fields are unordered**
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
{
nearestThing(location: { lon: 12.43, lat: -53.211 })
}
```
```graphql example
@@ -981,60 +1089,59 @@ ObjectValue : { ObjectField+ }
## Variables
Variable : $ Name
VariableDefinitions : ( VariableDefinition+ )
-VariableDefinition : Variable : Type DefaultValue?
+VariableDefinition : Variable : Type DefaultValue? Directives[Const]?
DefaultValue : = Value[Const]
-A GraphQL query can be parameterized with variables, maximizing query reuse,
+A GraphQL operation can be parameterized with variables, maximizing reuse,
and avoiding costly string building in clients at runtime.
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:
```graphql example
query getZuckProfile($devicePicSize: Int) {
user(id: 4) {
id
name
profilePic(size: $devicePicSize)
}
}
```
-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
{
"devicePicSize": 60
}
```
**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
Type :
- NamedType
- ListType
- NonNullType
@@ -1042,19 +1149,19 @@ Type :
NamedType : Name
ListType : [ Type ]
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**
Type : Name
* Let {name} be the string value of {Name}
* Let {type} be the type defined in the Schema named {name}
* {type} must not be {null}
@@ -1084,13 +1191,36 @@ validation behavior in a GraphQL document.
In some cases, you need to provide options to alter GraphQL's execution
behavior in ways field arguments will not suffice, such as conditionally
including or skipping a field. Directives provide this by describing additional information to the executor.
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.
+they may be exposed via directives. GraphQL services and tools may also provide
+any additional *custom directive* beyond those described here.
+
+**Directive order is significant**
+
+Directives may be provided in a specific syntactic order which may have semantic interpretation.
+
+These two type definitions may have different semantic meaning:
+
+```graphql example
+type Person
+ @addExternalFields(source: "profiles")
+ @excludeField(name: "photo") {
+ name: String
+}
+```
+
+```graphql example
+type Person
+ @excludeField(name: "photo")
+ @addExternalFields(source: "profiles") {
+ name: String
+}
+```
~~~
</details>
<details>
<summary>spec/Section 3 -- Type System.md</summary>
~~~diff
@@ -1,51 +1,126 @@
# Type System
-The GraphQL Type system describes the capabilities of a GraphQL server 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.
+The GraphQL Type system describes the capabilities of a GraphQL service and is
+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+
TypeSystemDefinition :
- SchemaDefinition
- TypeDefinition
- DirectiveDefinition
The GraphQL language includes an
[IDL](https://en.wikipedia.org/wiki/Interface_description_language) used to
describe a GraphQL service's type system. Tools may use this definition language
to provide utilities such as client code generation or service boot-strapping.
-GraphQL tools which only seek to provide GraphQL query execution may choose not
-to parse {TypeSystemDefinition}.
-
-A GraphQL Document which contains {TypeSystemDefinition} must not be executed;
-GraphQL execution services which receive a GraphQL Document containing type
-system definitions should return a descriptive error.
+GraphQL tools or services which only seek to execute GraphQL requests and not
+construct a new GraphQL schema may choose not to allow {TypeSystemDefinition}.
+Tools which only seek to produce schema and not execute requests may choose to
+only allow {TypeSystemDocument} and not allow {ExecutableDefinition} or
+{TypeSystemExtension} but should provide a descriptive error if present.
Note: The type system definition language is used throughout the remainder of
this specification document when illustrating example type systems.
## Type System Extensions
+TypeSystemExtensionDocument : TypeSystemDefinitionOrExtension+
+
+TypeSystemDefinitionOrExtension :
+ - TypeSystemDefinition
+ - TypeSystemExtension
+
TypeSystemExtension :
- SchemaExtension
- TypeExtension
-Type system extensions are used to represent a GraphQL type system which has been
-extended from some original type system. For example, this might be used by a
-local service to represent data a GraphQL client only accesses locally, or by a
-GraphQL service which is itself an extension of another GraphQL service.
+Type system extensions are used to represent a GraphQL type system which has
+been extended from some original type system. For example, this might be used by
+a local service to represent data a GraphQL client only accesses locally, or by
+a GraphQL service which is itself an extension of another GraphQL service.
+
+Tools which only seek to produce and extend schema and not execute requests may
+choose to only allow {TypeSystemExtensionDocument} and not allow
+{ExecutableDefinition} but should provide a descriptive error if present.
+
+
+## Descriptions
+
+Description : StringValue
+
+Documentation is a first-class feature of GraphQL type systems. To ensure
+the documentation of a GraphQL service remains consistent with its capabilities,
+descriptions of GraphQL definitions are provided alongside their definitions and
+made available via introspection.
+
+To allow GraphQL service designers to easily publish documentation alongside the
+capabilities of a GraphQL service, GraphQL descriptions are defined using the
+Markdown syntax (as specified by [CommonMark](https://commonmark.org/)). In the
+type system definition language, these description strings (often {BlockString})
+occur immediately before the definition they describe.
+
+GraphQL schema and all other definitions (e.g. types, fields, arguments, etc.)
+which can be described should provide a {Description} unless they are considered
+self descriptive.
+
+As an example, this simple GraphQL schema is well described:
+
+```raw graphql example
+"""
+A simple GraphQL schema which is well described.
+"""
+schema {
+ query: Query
+}
+
+"""
+Root type for all your query operations
+"""
+type Query {
+ """
+ Translates a string from a given language into a different language.
+ """
+ translate(
+ "The original language that `text` is provided in."
+ fromLanguage: Language
+
+ "The translated language to be returned."
+ toLanguage: Language
+
+ "The text to be translated."
+ text: String
+ ): String
+}
+
+"""
+The set of languages supported by `translate`.
+"""
+enum Language {
+ "English"
+ EN
+
+ "French"
+ FR
+
+ "Chinese"
+ CH
+}
+```
## Schema
-SchemaDefinition : schema Directives[Const]? { RootOperationTypeDefinition+ }
+SchemaDefinition : Description? schema Directives[Const]? { RootOperationTypeDefinition+ }
RootOperationTypeDefinition : OperationType : NamedType
A GraphQL service's collective type system capabilities are referred to as that
service's "schema". A schema is defined in terms of the types and directives it
supports as well as the root operation types for each kind of operation:
query, mutation, and subscription; this determines the place in the type system
where those operations begin.
@@ -64,60 +139,64 @@ begins with {"__"} (two underscores), as this is used exclusively by GraphQL's
introspection system.
### Root Operation Types
A schema defines the initial root operation type for each kind of operation it
supports: query, mutation, and subscription; this determines the place in the
type system where those operations begin.
-The `query` root operation type must be provided and must be an Object type.
+The {`query`} root operation type must be provided and must be an Object type.
-The `mutation` root operation type is optional; if it is not provided, the
+The {`mutation`} root operation type is optional; if it is not provided, the
service does not support mutations. If it is provided, it must be an
Object type.
-Similarly, the `subscription` root operation type is also optional; if it is not
-provided, the service does not support subscriptions. If it is provided, it must
-be an Object type.
+Similarly, the {`subscription`} root operation type is also optional; if it is
+not provided, the service does not support subscriptions. If it is provided, it
+must be an Object type.
-The fields on the `query` root operation type indicate what fields are available
-at the top level of a GraphQL query. For example, a basic GraphQL query like:
+The {`query`}, {`mutation`}, and {`subscription`} root types must all be
+different types if provided.
+
+The fields on the {`query`} root operation type indicate what fields are
+available at the top level of a GraphQL query operation.
+
+For example, this example operation:
```graphql example
query {
myName
}
```
-Is valid when the `query` root operation type has a field named "myName".
+is only valid when the {`query`} root operation type has a field named "myName":
```graphql example
type Query {
myName: String
}
```
-Similarly, the following mutation is valid if a `mutation` root operation type
-has a field named "setName". Note that the `query` and `mutation` root types
-must be different types.
+Similarly, the following mutation is only valid if the {`mutation`} root
+operation type has a field named "setName".
```graphql example
mutation {
setName(name: "Zuck") {
newName
}
}
```
When using the type system definition language, a document must include at most
-one `schema` definition.
+one {`schema`} definition.
In this example, a GraphQL schema is defined with both query and mutation
-root types:
+root operation types:
```graphql example
schema {
query: MyQueryRootType
mutation: MyMutationRootType
}
type MyQueryRootType {
@@ -127,107 +206,55 @@ type MyQueryRootType {
type MyMutationRootType {
setSomeField(to: String): String
}
```
**Default Root Operation Type Names**
While any type can be the root operation type for a GraphQL operation, the type
-system definition language can omit the schema definition when the `query`,
-`mutation`, and `subscription` root types are named `Query`, `Mutation`, and
-`Subscription` respectively.
+system definition language can omit the schema definition when the {`query`},
+{`mutation`}, and {`subscription`} root types are named {"Query"}, {"Mutation"},
+and {"Subscription"} respectively.
Likewise, when representing a GraphQL schema using the type system definition
language, a schema definition should be omitted if it only uses the default root
operation type names.
This example describes a valid complete GraphQL schema, despite not explicitly
-including a `schema` definition. The `Query` type is presumed to be the `query`
-root operation type of the schema.
+including a {`schema`} definition. The {"Query"} type is presumed to be the
+{`query`} root operation type of the schema.
```graphql example
type Query {
someField: String
}
```
### Schema Extension
SchemaExtension :
- - extend schema Directives[Const]? { OperationTypeDefinition+ }
- - extend schema Directives[Const]
+ - extend schema Directives[Const]? { RootOperationTypeDefinition+ }
+ - extend schema Directives[Const] [lookahead != `{`]
Schema extensions are used to represent a schema which has been extended from
an original schema. For example, this might be used by a GraphQL service which
adds additional operation types, or additional directives to an existing schema.
+Note: Schema extensions without additional operation type definitions must not
+be followed by a {`{`} (such as a query shorthand) to avoid parsing ambiguity.
+The same limitation applies to the type definitions and extensions below.
+
**Schema Validation**
Schema extensions have the potential to be invalid if incorrectly defined.
1. The Schema must already be defined.
-2. Any directives provided must not already apply to the original Schema.
-
-
-## Descriptions
-
-Description : StringValue
-
-Documentation is first-class feature of GraphQL type systems. To ensure
-the documentation of a GraphQL service remains consistent with its capabilities,
-descriptions of GraphQL definitions are provided alongside their definitions and
-made available via introspection.
-
-To allow GraphQL service designers to easily publish documentation alongside the
-capabilities of a GraphQL service, GraphQL descriptions are defined using the
-Markdown syntax (as specified by [CommonMark](http://commonmark.org/)). In the
-type system definition language, these description strings (often {BlockString})
-occur immediately before the definition they describe.
-
-All GraphQL types, fields, arguments and other definitions which can be
-described should provide a {Description} unless they are considered self
-descriptive.
-
-As an example, this simple GraphQL schema is well described:
-
-```graphql example
-"""
-A simple GraphQL schema which is well described.
-"""
-type Query {
- """
- Translates a string from a given language into a different language.
- """
- translate(
- "The original language that `text` is provided in."
- fromLanguage: Language
-
- "The translated language to be returned."
- toLanguage: Language
-
- "The text to be translated."
- text: String
- ): String
-}
-
-"""
-The set of languages supported by `translate`.
-"""
-enum Language {
- "English"
- EN
-
- "French"
- FR
-
- "Chinese"
- CH
-}
-```
+2. Any non-repeatable directives provided must not already apply to the
+ original Schema.
## Types
TypeDefinition :
- ScalarTypeDefinition
- ObjectTypeDefinition
- InterfaceTypeDefinition
@@ -244,53 +271,54 @@ are enumerable. GraphQL offers an `Enum` type in those cases, where the type
specifies the space of valid responses.
Scalars and Enums form the leaves in response trees; the intermediate levels are
`Object` types, which define a set of fields, where each field is another
type in the system, allowing the definition of arbitrary type hierarchies.
GraphQL supports two abstract types: interfaces and unions.
-An `Interface` defines a list of fields; `Object` types that implement that
-interface are guaranteed to implement those fields. Whenever the type system
-claims it will return an interface, it will return a valid implementing type.
+An `Interface` defines a list of fields; `Object` types and other Interface
+types which implement this Interface are guaranteed to implement those fields.
+Whenever a field claims it will return an Interface type, it will return a
+valid implementing Object type during execution.
A `Union` defines a list of possible types; similar to interfaces, whenever the
type system claims a union will be returned, one of the possible types will be
returned.
Finally, oftentimes it is useful to provide complex structs as inputs to
GraphQL field arguments or variables; the `Input Object` type allows the schema
to define exactly what data is expected.
### Wrapping Types
All of the types so far are assumed to be both nullable and singular: e.g. a
scalar string returns either null or a singular string.
-A GraphQL schema may describe that a field represents list of another types;
+A GraphQL schema may describe that a field represents a list of another type;
the `List` type is provided for this reason, and wraps another type.
Similarly, the `Non-Null` type wraps another type, and denotes that the
-resulting value will never be {null} (and that an error cannot result in a
+resulting value will never be {null} (and that a field error cannot result in a
{null} value).
These two types are referred to as "wrapping types"; non-wrapping types are
referred to as "named types". A wrapping type has an underlying named type,
found by continually unwrapping the type until a named type is found.
### Input and Output Types
Types are used throughout GraphQL to describe both the values accepted as input
to arguments and variables as well as the values output by fields. These two
uses categorize types as *input types* and *output types*. Some kinds of types,
like Scalar and Enum types, can be used as both input types and output types;
-other kinds types can only be used in one or the other. Input Object types can
+other kinds of types can only be used in one or the other. Input Object types can
only be used as input types. Object, Interface, and Union types can only be used
as output types. Lists and Non-Null types may be used as input types or output
types depending on how the wrapped type may be used.
IsInputType(type) :
* If {type} is a List type or Non-Null type:
* Let {unwrappedType} be the unwrapped type of {type}.
* Return IsInputType({unwrappedType})
@@ -322,273 +350,319 @@ from some original type. For example, this might be used by a local service to
represent additional fields a GraphQL client only accesses locally.
## Scalars
ScalarTypeDefinition : Description? scalar Name Directives[Const]?
Scalar types represent primitive leaf values in a GraphQL type system. GraphQL
-responses take the form of a hierarchical tree; the leaves on these trees are
-GraphQL scalars.
-
-All GraphQL scalars are representable as strings, though depending on the
-response format being used, there may be a more appropriate primitive for the
-given scalar type, and server should use those types when appropriate.
-
-GraphQL provides a number of built-in scalars, but type systems can add
-additional scalars with semantic meaning. For example, a GraphQL system could
-define a scalar called `Time` which, while serialized as a string, promises to
-conform to ISO-8601. When querying a field of type `Time`, you can then rely on
-the ability to parse the result with an ISO-8601 parser and use a
-client-specific primitive for time. Another example of a potentially useful
-custom scalar is `Url`, which serializes as a string, but is guaranteed by
-the server to be a valid URL.
+responses take the form of a hierarchical tree; the leaves of this tree are
+typically GraphQL Scalar types (but may also be Enum types or {null} values).
+
+GraphQL provides a number of built-in scalars which are fully defined in the
+sections below, however type systems may also add additional custom scalars to
+introduce additional semantic meaning.
+
+**Built-in Scalars**
+
+GraphQL specifies a basic set of well-defined Scalar types: {Int}, {Float},
+{String}, {Boolean}, and {ID}. A GraphQL framework should support all of these
+types, and a GraphQL service which provides a type by these names must adhere to
+the behavior described for them in this document. As an example, a service must
+not include a type called {Int} and use it to represent 64-bit numbers,
+internationalization information, or anything other than what is defined in
+this document.
+
+When returning the set of types from the `__Schema` introspection type, all
+referenced built-in scalars must be included. If a built-in scalar type is not
+referenced anywhere in a schema (there is no field, argument, or input field of
+that type) then it must not be included.
+
+When representing a GraphQL schema using the type system definition language,
+all built-in scalars must be omitted for brevity.
+
+**Custom Scalars**
+
+GraphQL services may use custom scalar types in addition to the built-in
+scalars. For example, a GraphQL service could define a scalar called `UUID`
+which, while serialized as a string, conforms to [RFC 4122](https://tools.ietf.org/html/rfc4122).
+When querying a field of type `UUID`, you can then rely on the ability to parse
+the result with a RFC 4122 compliant parser. Another example of a potentially
+useful custom scalar is `URL`, which serializes as a string, but is guaranteed
+by the server to be a valid URL.
+
+:: When defining a custom scalar, GraphQL services should provide a *scalar
+specification URL* via the `@specifiedBy` directive or the `specifiedByURL`
+introspection field. This URL must link to a human-readable specification of the
+data format, serialization, and coercion rules for the scalar.
+
+For example, a GraphQL service providing a `UUID` scalar may link to RFC 4122,
+or some custom document defining a reasonable subset of that RFC. If a *scalar
+specification URL* is present, systems and tools that are aware of it should
+conform to its described rules.
```graphql example
-scalar Time
-scalar Url
+scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
+scalar URL @specifiedBy(url: "https://tools.ietf.org/html/rfc3986")
```
-A server may omit any of the built-in scalars from its schema, for example if a
-schema does not refer to a floating-point number, then it must not include the
-`Float` type. However, if a schema includes a type with the name of one of the
-types described here, it must adhere to the behavior described. As an example,
-a server must not include a type called `Int` and use it to represent
-128-bit numbers, internationalization information, or anything other than what
-is defined in this document.
+Custom *scalar specification URL*s should provide a single, stable format to
+avoid ambiguity. If the linked specification is in flux, the service should link
+to a fixed version rather than to a resource which might change.
-When representing a GraphQL schema using the type system definition language,
-the built-in scalar types should be omitted for brevity.
+Custom *scalar specification URL*s should not be changed once defined. Doing so
+would likely disrupt tooling or could introduce breaking changes within the
+linked specification's contents.
-**Result Coercion**
+Built-in scalar types must not provide a *scalar specification URL* as they are
+specified by this document.
+
+Note: Custom scalars should also summarize the specified format and provide
+examples in their description.
-A GraphQL server, when preparing a field of a given scalar type, must uphold the
+**Result Coercion and Serialization**
+
+A GraphQL service, when preparing a field of a given scalar type, must uphold the
contract the scalar type describes, either by coercing the value or producing a
-field error if a value cannot be coerced or if coercion may result in data loss.
+[field error](#sec-Errors.Field-errors) if a value cannot be coerced or if
+coercion may result in data loss.
A GraphQL service may decide to allow coercing different internal types to the
-expected return type. For example when coercing a field of type `Int` a boolean
-`true` value may produce `1` or a string value `"123"` may be parsed as base-10
-`123`. However if internal type coercion cannot be reasonably performed without
+expected return type. For example when coercing a field of type {Int} a boolean
+{true} value may produce {1} or a string value {"123"} may be parsed as base-10
+{123}. However if internal type coercion cannot be reasonably performed without
losing information, then it must raise a field error.
-Since this coercion behavior is not observable to clients of the GraphQL server,
+Since this coercion behavior is not observable to clients of the GraphQL service,
the precise rules of coercion are left to the implementation. The only
-requirement is that the server must yield values which adhere to the expected
+requirement is that the service must yield values which adhere to the expected
Scalar type.
+GraphQL scalars are serialized according to the serialization format being used.
+There may be a most appropriate serialized primitive for each given scalar type,
+and the service should produce each primitive where appropriate.
+
+See [Serialization Format](#sec-Serialization-Format) for more detailed
+information on the serialization of scalars in common JSON and other formats.
+
**Input Coercion**
-If a GraphQL server expects a scalar type as input to an argument, coercion
+If a GraphQL service expects a scalar type as input to an argument, coercion
is observable and the rules must be well defined. If an input value does not
-match a coercion rule, a query error must be raised.
+match a coercion rule, a [request error](#sec-Errors.Request-errors) must be
+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
input value.
For all types below, with the exception of Non-Null, if the explicit value
{null} is provided, then the result of input coercion is {null}.
-**Built-in Scalars**
-
-GraphQL provides a basic set of well-defined Scalar types. A GraphQL server
-should support all of these types, and a GraphQL server which provide a type by
-these names must adhere to the behavior described below.
-
### Int
The Int scalar type represents a signed 32-bit numeric non-fractional value.
Response formats that support a 32-bit integer or a number type should use
that type to represent this scalar.
**Result Coercion**
-Fields returning the type `Int` expect to encounter 32-bit integer
+Fields returning the type {Int} expect to encounter 32-bit integer
internal values.
-GraphQL servers may coerce non-integer internal values to integers when
+GraphQL services may coerce non-integer internal values to integers when
reasonable without losing information, otherwise they must raise a field error.
Examples of this may include returning `1` for the floating-point number `1.0`,
or returning `123` for the string `"123"`. In scenarios where coercion may lose
data, raising a field error is more appropriate. For example, a floating-point
number `1.2` should raise a field error instead of being truncated to `1`.
If the integer internal value represents a value less than -2<sup>31</sup> or
greater than or equal to 2<sup>31</sup>, a field error should be raised.
**Input Coercion**
When expected as an input type, only integer input values are accepted. All
-other input values, including strings with numeric content, must raise a query
+other input values, including strings with numeric content, must raise a request
error indicating an incorrect type. If the integer input value represents a
value less than -2<sup>31</sup> or greater than or equal to 2<sup>31</sup>, a
-query error should be raised.
+request error should be raised.
Note: Numeric integer values larger than 32-bit should either use String or a
custom-defined Scalar type, as not all platforms and transports support
encoding integer numbers larger than 32-bit.
### Float
-The Float scalar type represents signed double-precision fractional values
-as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
-Response formats that support an appropriate double-precision number type
-should use that type to represent this scalar.
+The Float scalar type represents signed double-precision finite values as
+specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).
+Response formats that support an appropriate double-precision number type should
+use that type to represent this scalar.
**Result Coercion**
-Fields returning the type `Float` expect to encounter double-precision
+Fields returning the type {Float} expect to encounter double-precision
floating-point internal values.
-GraphQL servers may coerce non-floating-point internal values to `Float` when
+GraphQL services may coerce non-floating-point internal values to {Float} when
reasonable without losing information, otherwise they must raise a field error.
Examples of this may include returning `1.0` for the integer number `1`, or
`123.0` for the string `"123"`.
+Non-finite floating-point internal values ({NaN} and {Infinity}) cannot be
+coerced to {Float} and must raise a field error.
+
**Input Coercion**
When expected as an input type, both integer and float input values are
accepted. Integer input values are coerced to Float by adding an empty
fractional part, for example `1.0` for the integer input value `1`. All
-other input values, including strings with numeric content, must raise a query
-error indicating an incorrect type. If the integer input value represents a
-value not representable by IEEE 754, a query error should be raised.
+other input values, including strings with numeric content, must raise a request
+error indicating an incorrect type. If the input value otherwise represents a
+value not representable by finite IEEE 754 (e.g. {NaN}, {Infinity}, or a value
+outside the available precision), a request error must be raised.
### String
-The String scalar type represents textual data, represented as UTF-8 character
-sequences. The String type is most often used by GraphQL to represent free-form
-human-readable text. All response formats must support string representations,
-and that representation must be used here.
+The String scalar type represents textual data, represented as a sequence of
+Unicode code points. The String type is most often used by GraphQL to
+represent free-form human-readable text. How the String is encoded internally
+(for example UTF-8) is left to the service implementation. All response
+serialization formats must support a string representation (for example, JSON
+Unicode strings), and that representation must be used to serialize this type.
**Result Coercion**
-Fields returning the type `String` expect to encounter UTF-8 string internal values.
+Fields returning the type {String} expect to encounter Unicode string values.
-GraphQL servers may coerce non-string raw values to `String` when reasonable
+GraphQL services may coerce non-string raw values to {String} when reasonable
without losing information, otherwise they must raise a field error. Examples of
this may include returning the string `"true"` for a boolean true value, or the
string `"1"` for the integer `1`.
**Input Coercion**
-When expected as an input type, only valid UTF-8 string input values are
-accepted. All other input values must raise a query error indicating an
+When expected as an input type, only valid Unicode string input values are
+accepted. All other input values must raise a request error indicating an
incorrect type.
### Boolean
The Boolean scalar type represents `true` or `false`. Response formats should
use a built-in boolean type if supported; otherwise, they should use their
representation of the integers `1` and `0`.
**Result Coercion**
-Fields returning the type `Boolean` expect to encounter boolean internal values.
+Fields returning the type {Boolean} expect to encounter boolean internal values.
-GraphQL servers may coerce non-boolean raw values to `Boolean` when reasonable
+GraphQL services may coerce non-boolean raw values to {Boolean} when reasonable
without losing information, otherwise they must raise a field error. Examples of
this may include returning `true` for non-zero numbers.
**Input Coercion**
When expected as an input type, only boolean input values are accepted. All
-other input values must raise a query error indicating an incorrect type.
+other input values must raise a request error indicating an incorrect type.
### ID
The ID scalar type represents a unique identifier, often used to refetch an
object or as the key for a cache. The ID type is serialized in the same way as
-a `String`; however, it is not intended to be human-readable. While it is
-often numeric, it should always serialize as a `String`.
+a {String}; however, it is not intended to be human-readable. While it is
+often numeric, it should always serialize as a {String}.
**Result Coercion**
GraphQL is agnostic to ID format, and serializes to string to ensure consistency
across many formats ID could represent, from small auto-increment numbers, to
large 128-bit random numbers, to base64 encoded values, or string values of a
-format like [GUID](http://en.wikipedia.org/wiki/Globally_unique_identifier).
+format like [GUID](https://en.wikipedia.org/wiki/Globally_unique_identifier).
-GraphQL servers should coerce as appropriate given the ID formats they expect.
+GraphQL services should coerce as appropriate given the ID formats they expect.
When coercion is not possible they must raise a field error.
**Input Coercion**
-When expected as an input type, any string (such as `"4"`) or integer (such
-as `4`) input value should be coerced to ID as appropriate for the ID formats
-a given GraphQL server expects. Any other input value, including float input
-values (such as `4.0`), must raise a query error indicating an incorrect type.
+When expected as an input type, any string (such as `"4"`) or integer (such as
+`4` or `-4`) input value should be coerced to ID as appropriate for the ID
+formats a given GraphQL service expects. Any other input value, including float
+input values (such as `4.0`), must raise a request error indicating an incorrect
+type.
### Scalar Extensions
ScalarTypeExtension :
- extend scalar Name Directives[Const]
Scalar type extensions are used to represent a scalar type which has been
extended from some original scalar type. For example, this might be used by a
GraphQL tool or service which adds directives to an existing scalar.
**Type Validation**
Scalar type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be a Scalar type.
-2. Any directives provided must not already apply to the original Scalar type.
+2. Any non-repeatable directives provided must not already apply to the
+ original Scalar type.
## Objects
-ObjectTypeDefinition : Description? type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition?
+ObjectTypeDefinition :
+ - Description? type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
+ - Description? type Name ImplementsInterfaces? Directives[Const]? [lookahead != `{`]
ImplementsInterfaces :
- - implements `&`? NamedType
- ImplementsInterfaces & NamedType
+ - implements `&`? NamedType
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
introspection system.
For example, a type `Person` could be described as:
```graphql example
type Person {
name: String
age: Int
picture: Url
}
```
-Where `name` is a field that will yield a `String` value, and `age` is a field
-that will yield an `Int` value, and `picture` is a field that will yield a
+Where `name` is a field that will yield a {String} value, and `age` is a field
+that will yield an {Int} value, and `picture` is a field that will yield a
`Url` value.
A query of an object value must select at least one field. This selection of
fields will yield an ordered map containing exactly the subset of the object
queried, which should be represented in the order in which they were queried.
Only fields that are declared on the object type may validly be queried on
that object.
@@ -640,18 +714,18 @@ For example, the `Person` type might include a `relationship`:
type Person {
name: String
age: Int
picture: Url
relationship: 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
{
name
relationship
}
```
@@ -675,17 +749,17 @@ And will yield the subset of each object type queried:
"name": "Priscilla Chan"
}
}
```
**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.
Response serialization formats capable of representing ordered maps should
maintain this ordering. Serialization formats which can only represent unordered
maps (such as JSON) should retain this order textually. That is, if two fields
`{foo, bar}` were queried in that order, the resulting JSON serialization
@@ -798,41 +872,64 @@ of rules must be adhered to by every Object type in a GraphQL schema.
2. The field must not have a name which begins with the
characters {"__"} (two underscores).
3. The field must return a type where {IsOutputType(fieldType)} returns {true}.
4. For each argument of the field:
1. The argument must not have a name which begins with the
characters {"__"} (two underscores).
2. The argument must accept a type where {IsInputType(argumentType)}
returns {true}.
-4. An object type may declare that it implements one or more unique interfaces.
-5. An object type must be a super-set of all interfaces it implements:
- 1. The object type must include a field of the same name for every field
- defined in an interface.
- 1. The object field must be of a type which is equal to or a sub-type of
- the interface field (covariant).
- 1. An object field type is a valid sub-type if it is equal to (the same
- type as) the interface field type.
- 2. An object field type is a valid sub-type if it is an Object type and
- the interface field type is either an Interface type or a Union type
- and the object field type is a possible type of the interface field
- type.
- 3. An object field type is a valid sub-type if it is a List type and
- the interface field type is also a List type and the list-item type
- of the object field type is a valid sub-type of the list-item type
- of the interface field type.
- 4. An object field type is a valid sub-type if it is a Non-Null variant
- of a valid sub-type of the interface field type.
- 2. The object field must include an argument of the same name for every
- argument defined in the interface field.
- 1. The object field argument must accept the same type (invariant) as
- the interface field argument.
- 3. The object field may include additional arguments not defined in the
- interface field, but any additional argument must not be required, e.g.
- must not be of a non-nullable type.
+3. An object type may declare that it implements one or more unique interfaces.
+4. An object type must be a super-set of all interfaces it implements:
+ 1. Let this object type be {objectType}.
+ 2. For each interface declared implemented as {interfaceType},
+ {IsValidImplementation(objectType, interfaceType)} must be {true}.
+
+IsValidImplementation(type, implementedType):
+
+ 1. If {implementedType} declares it implements any interfaces,
+ {type} must also declare it implements those interfaces.
+ 2. {type} must include a field of the same name for every field
+ defined in {implementedType}.
+ 1. Let {field} be that named field on {type}.
+ 2. Let {implementedField} be that named field on {implementedType}.
+ 3. {field} must include an argument of the same name for every argument
+ defined in {implementedField}.
+ 1. That named argument on {field} must accept the same type
+ (invariant) as that named argument on {implementedField}.
+ 4. {field} may include additional arguments not defined in
+ {implementedField}, but any additional argument must not be required,
+ e.g. must not be of a non-nullable type.
+ 5. {field} must return a type which is equal to or a sub-type of
+ (covariant) the return type of {implementedField} field's return type:
+ 1. Let {fieldType} be the return type of {field}.
+ 2. Let {implementedFieldType} be the return type of {implementedField}.
+ 3. {IsValidImplementationFieldType(fieldType, implementedFieldType)}
+ must be {true}.
+
+IsValidImplementationFieldType(fieldType, implementedFieldType):
+ 1. If {fieldType} is a Non-Null type:
+ 1. Let {nullableType} be the unwrapped nullable type of {fieldType}.
+ 2. Let {implementedNullableType} be the unwrapped nullable type
+ of {implementedFieldType} if it is a Non-Null type, otherwise let it be
+ {implementedFieldType} directly.
+ 3. Return {IsValidImplementationFieldType(nullableType, implementedNullableType)}.
+ 2. If {fieldType} is a List type and {implementedFieldType} is also a List type:
+ 1. Let {itemType} be the unwrapped item type of {fieldType}.
+ 2. Let {implementedItemType} be the unwrapped item type
+ of {implementedFieldType}.
+ 3. Return {IsValidImplementationFieldType(itemType, implementedItemType)}.
+ 3. If {fieldType} is the same type as {implementedFieldType} then return {true}.
+ 4. If {fieldType} is an Object type and {implementedFieldType} is
+ a Union type and {fieldType} is a possible type of {implementedFieldType}
+ then return {true}.
+ 5. If {fieldType} is an Object or Interface type and {implementedFieldType}
+ is an Interface type and {fieldType} declares it implements
+ {implementedFieldType} then return {true}.
+ 6. Otherwise return {false}.
### Field Arguments
ArgumentsDefinition : ( InputValueDefinition+ )
InputValueDefinition : Description? Name : Type DefaultValue? Directives[Const]?
@@ -850,64 +947,64 @@ determine what size of an image to return.
```graphql example
type Person {
name: String
picture(size: Int): Url
}
```
-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
{
name
picture(size: 600)
}
```
-May yield the result:
+May return the result:
```json example
{
"name": "Mark Zuckerberg",
"picture": "http://some.cdn/picture_600.jpg"
}
```
The type of an object field argument must be an input type (any type except an
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:
```graphql example
type ExampleType {
oldField: String @deprecated
}
```
### Object Extensions
ObjectTypeExtension :
- extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
- - extend type Name ImplementsInterfaces? Directives[Const]
- - extend type Name ImplementsInterfaces
+ - extend type Name ImplementsInterfaces? Directives[Const] [lookahead != `{`]
+ - extend type Name ImplementsInterfaces [lookahead != `{`]
Object type extensions are used to represent a type which has been extended from
some original type. For example, this might be used to represent local data, or
by a GraphQL service which is itself an extension of another GraphQL service.
In this example, a local data field is added to a `Story` type:
```graphql example
@@ -929,30 +1026,33 @@ extend type User @addedDirective
Object type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be an Object type.
2. The fields of an Object type extension must have unique names; no two fields
may share the same name.
3. Any fields of an Object type extension must not be already defined on the
original Object type.
-4. Any directives provided must not already apply to the original Object type.
+4. Any non-repeatable directives provided must not already apply to the
+ original Object type.
5. Any interfaces provided must not be already implemented by the original
Object type.
6. The resulting extended object type must be a super-set of all interfaces it
implements.
## Interfaces
-InterfaceTypeDefinition : Description? interface Name Directives[Const]? FieldsDefinition?
+InterfaceTypeDefinition :
+ - Description? interface Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
+ - Description? interface Name ImplementsInterfaces? Directives[Const]? [lookahead != `{`]
GraphQL interfaces represent a list of named fields and their arguments. GraphQL
-objects can then implement these interfaces which requires that the object type
-will define all fields defined by those interfaces.
+objects and interfaces can then implement these interfaces which requires that
+the implementing type will define all fields defined by those interfaces.
Fields on a GraphQL interface have the same rules as fields on a GraphQL object;
their type can be Scalar, Object, Enum, Interface, or Union, or any wrapping
type whose base type is one of those five.
For example, an interface `NamedEntity` may describe a required field and types
such as `Person` or `Business` may then implement this interface to guarantee
this field will always exist.
@@ -989,59 +1089,116 @@ To continue the example, a `Contact` might refer to `NamedEntity`.
```graphql example
type Contact {
entity: NamedEntity
phoneNumber: String
address: String
}
```
-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
{
entity {
name
}
phoneNumber
}
```
-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
{
entity {
name
age
}
phoneNumber
}
```
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
{
entity {
name
... on Person {
age
}
- },
+ }
phoneNumber
}
```
+**Interfaces Implementing Interfaces**
+
+When defining an interface that implements another interface, the implementing
+interface must define each field that is specified by the implemented interface.
+For example, the interface Resource must define the field id to implement the
+Node interface:
+
+```raw graphql example
+interface Node {
+ id: ID!
+}
+
+interface Resource implements Node {
+ id: ID!
+ url: String
+}
+```
+
+Transitively implemented interfaces (interfaces implemented by the interface
+that is being implemented) must also be defined on an implementing type or
+interface. For example, `Image` cannot implement `Resource` without also
+implementing `Node`:
+
+```raw graphql example
+interface Node {
+ id: ID!
+}
+
+interface Resource implements Node {
+ id: ID!
+ url: String
+}
+
+interface Image implements Resource & Node {
+ id: ID!
+ url: String
+ thumbnail: String
+}
+```
+
+Interface definitions must not contain cyclic references nor implement
+themselves. This example is invalid because `Node` and `Named` implement
+themselves and each other:
+
+```graphql counter-example
+interface Node implements Named & Node {
+ id: ID!
+ name: String
+}
+
+interface Named implements Node & Named {
+ id: ID!
+ name: String
+}
+```
+
+
**Result Coercion**
The interface type should have some way of determining which object a given
result corresponds to. Once it has done so, the result coercion of the interface
is the same as the result coercion of the object.
**Input Coercion**
@@ -1059,23 +1216,30 @@ Interface types have the potential to be invalid if incorrectly defined.
characters {"__"} (two underscores).
3. The field must return a type where {IsOutputType(fieldType)}
returns {true}.
4. For each argument of the field:
1. The argument must not have a name which begins with the
characters {"__"} (two underscores).
2. The argument must accept a type where {IsInputType(argumentType)}
returns {true}.
+3. An interface type may declare that it implements one or more unique
+ interfaces, but may not implement itself.
+4. An interface type must be a super-set of all interfaces it implements:
+ 1. Let this interface type be {implementingType}.
+ 2. For each interface declared implemented as {implementedType},
+ {IsValidImplementation(implementingType, implementedType)} must be {true}.
### Interface Extensions
InterfaceTypeExtension :
- - extend interface Name Directives[Const]? FieldsDefinition
- - extend interface Name Directives[Const]
+ - extend interface Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
+ - extend interface Name ImplementsInterfaces? Directives[Const] [lookahead != `{`]
+ - extend interface Name ImplementsInterfaces [lookahead != `{`]
Interface type extensions are used to represent an interface which has been
extended from some original interface. For example, this might be used to
represent common local data on many types, or by a GraphQL service which is
itself an extension of another GraphQL service.
In this example, an extended data field is added to a `NamedEntity` type along
with the types which implement it:
@@ -1108,40 +1272,44 @@ extend interface NamedEntity @addedDirective
Interface type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be an Interface type.
2. The fields of an Interface type extension must have unique names; no two
fields may share the same name.
3. Any fields of an Interface type extension must not be already defined on the
original Interface type.
-4. Any Object type which implemented the original Interface type must also be a
- super-set of the fields of the Interface type extension (which may be due to
- Object type extension).
-5. Any directives provided must not already apply to the original Interface type.
+4. Any Object or Interface type which implemented the original Interface type
+ must also be a super-set of the fields of the Interface type extension (which
+ may be due to Object type extension).
+5. Any non-repeatable directives provided must not already apply to the
+ original Interface type.
+6. The resulting extended Interface type must be a super-set of all Interfaces
+ it implements.
## Unions
UnionTypeDefinition : Description? union Name Directives[Const]? UnionMemberTypes?
UnionMemberTypes :
- - = `|`? NamedType
- UnionMemberTypes | NamedType
+ - = `|`? NamedType
GraphQL Unions represent an object that could be one of a list of GraphQL
Object types, but provides for no guaranteed fields between those types.
They also differ from interfaces in that Object types declare what interfaces
they implement, but are not aware of what unions contain them.
With interfaces and objects, only those fields defined on the type can be
queried directly; to query other fields on an interface, typed fragments
must be used. This is the same as for unions, but unions do not define any
fields, so **no** fields may be queried on this type without the use of
-type refining fragments or inline fragments.
+type refining fragments or inline fragments (with the exception of the
+meta-field {__typename}).
For example, we might define the following types:
```graphql example
union SearchResult = Photo | Person
type Person {
name: String
@@ -1153,32 +1321,30 @@ type Photo {
width: Int
}
type SearchQuery {
firstSearchResult: SearchResult
}
```
-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
{
firstSearchResult {
name
height
}
}
```
-Instead, the query would be:
+A valid operation includes typed fragments (in this example, inline fragments):
```graphql example
{
firstSearchResult {
... on Person {
name
}
... on Photo {
@@ -1186,17 +1352,17 @@ Instead, the query would be:
}
}
}
```
Union members may be defined with an optional leading `|` character to aid
formatting when representing a longer list of possible types:
-```graphql example
+```raw graphql example
union SearchResult =
| Photo
| Person
```
**Result Coercion**
The union type should have some way of determining which object a given result
@@ -1234,27 +1400,30 @@ Union type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be a Union type.
2. The member types of a Union type extension must all be Object base types;
Scalar, Interface and Union types must not be member types of a Union.
Similarly, wrapping types must not be member types of a Union.
3. All member types of a Union type extension must be unique.
4. All member types of a Union type extension must not already be a member of
the original Union type.
-5. Any directives provided must not already apply to the original Union type.
+5. Any non-repeatable directives provided must not already apply to the
+ original Union type.
## Enums
-EnumTypeDefinition : Description? enum Name Directives[Const]? EnumValuesDefinition?
+EnumTypeDefinition :
+ - Description? enum Name Directives[Const]? EnumValuesDefinition
+ - Description? enum Name Directives[Const]? [lookahead != `{`]
EnumValuesDefinition : { EnumValueDefinition+ }
EnumValueDefinition : Description? EnumValue Directives[Const]?
-GraphQL Enum types, like scalar types, also represent leaf values in a GraphQL
+GraphQL Enum types, like Scalar types, also represent leaf values in a GraphQL
type system. However Enum types describe the set of possible values.
Enums are not references for a numeric value, but are unique values in their own
right. They may serialize as a string: the name of the represented value.
In this example, an Enum type called `Direction` is defined:
```graphql example
@@ -1263,62 +1432,65 @@ enum Direction {
EAST
SOUTH
WEST
}
```
**Result Coercion**
-GraphQL servers must return one of the defined set of possible values. If a
+GraphQL services must return one of the defined set of possible values. If a
reasonable coercion is not possible they must raise a field error.
**Input Coercion**
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 query error.
+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
input value with the same name.
**Type Validation**
Enum types have the potential to be invalid if incorrectly defined.
1. An Enum type must define one or more unique enum values.
### Enum Extensions
EnumTypeExtension :
- extend enum Name Directives[Const]? EnumValuesDefinition
- - extend enum Name Directives[Const]
+ - extend enum Name Directives[Const] [lookahead != `{`]
Enum type extensions are used to represent an enum type which has been
extended from some original enum type. For example, this might be used to
represent additional local data, or by a GraphQL service which is itself an
extension of another GraphQL service.
**Type Validation**
Enum type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be an Enum type.
2. All values of an Enum type extension must be unique.
3. All values of an Enum type extension must not already be a value of
the original Enum.
-4. Any directives provided must not already apply to the original Enum type.
+4. Any non-repeatable directives provided must not already apply to the
+ original Enum type.
## Input Objects
-InputObjectTypeDefinition : Description? input Name Directives[Const]? InputFieldsDefinition?
+InputObjectTypeDefinition :
+ - Description? input Name Directives[Const]? InputFieldsDefinition
+ - Description? input Name Directives[Const]? [lookahead != `{`]
InputFieldsDefinition : { InputValueDefinition+ }
Fields may accept arguments to configure their behavior. These inputs are often
scalars or enums, but they sometimes need to represent more complex values.
A GraphQL Input Object defines a set of input fields; the input fields are either
scalars, enums, or other input objects. This allows arguments to accept
@@ -1334,51 +1506,105 @@ input Point2D {
```
Note: The GraphQL Object type ({ObjectTypeDefinition}) defined above is
inappropriate for re-use here, because Object types can contain fields that
define arguments or contain references to interfaces and unions, neither of
which is appropriate for use as an input argument. For this reason, input
objects have a separate type in the system.
+**Circular References**
+
+Input Objects are allowed to reference other Input Objects as field types. A
+circular reference occurs when an Input Object references itself either directly
+or through referenced Input Objects.
+
+Circular references are generally allowed, however they may not be defined as an
+unbroken chain of Non-Null singular fields. Such Input Objects are invalid
+because there is no way to provide a legal value for them.
+
+This example of a circularly-referenced input type is valid as the field `self`
+may be omitted or the value {null}.
+
+```graphql example
+input Example {
+ self: Example
+ value: String
+}
+```
+
+This example is also valid as the field `self` may be an empty List.
+
+```graphql example
+input Example {
+ self: [Example!]!
+ value: String
+}
+```
+
+This example of a circularly-referenced input type is invalid as the field
+`self` cannot be provided a finite value.
+
+```graphql counter-example
+input Example {
+ value: String
+ self: Example!
+}
+```
+
+This example is also invalid, as there is a non-null singular circular reference
+via the `First.second` and `Second.first` fields.
+
+```graphql counter-example
+input First {
+ second: Second!
+ value: String
+}
+
+input Second {
+ first: First!
+ value: String
+}
+```
+
**Result Coercion**
An input object is never a valid result. Input Object types cannot be the return
type of an Object or Interface field.
**Input Coercion**
The value for an input object should be an input object literal or an unordered
-map supplied by a variable, otherwise a query error must be thrown. In either
+map supplied by a variable, otherwise a request error must be raised. In either
case, the input object literal or unordered map must not contain any entries
-with names not defined by a field of this input object type, otherwise an error
-must be thrown.
+with names not defined by a field of this input object type, otherwise a
+response error must be raised.
The result of coercion is an unordered map with an entry for each field both
defined by the input object type and for which a value exists. The resulting map
is constructed with the following rules:
* If no value is provided for a defined input object field and that field
definition provides a default value, the default value should be used. If no
default value is provided and the input object field's type is non-null, an
- error should be thrown. Otherwise, if the field is not required, then no entry
+ error should be raised. Otherwise, if the field is not required, then no entry
is added to the coerced unordered map.
* If the value {null} was provided for an input object field, and the field's
type is not a non-null type, an entry in the coerced unordered map is given
the value {null}. In other words, there is a semantic difference between the
explicitly provided value {null} versus having not provided a value.
* If a literal value is provided for an input object field, an entry in the
coerced unordered map is given the result of coercing that value according
to the input coercion rules for the type of that field.
* If a variable is provided for an input object field, the runtime value of that
variable must be used. If the runtime value is {null} and the field type
- is non-null, a field error must be thrown. If no runtime value is provided,
+ is non-null, a field error must be raised. If no runtime value is provided,
the variable definition's default value should be used. If the variable
definition does not provide a default value, the input object field
definition's default value should be used.
Following are examples of input coercion for an input object type with a
`String` field `a` and a required (non-null) `Int!` field `b`:
```graphql example
@@ -1393,17 +1619,17 @@ Literal Value | Variables | Coerced Value
`{ a: "abc", b: 123 }` | `{}` | `{ a: "abc", b: 123 }`
`{ a: null, b: 123 }` | `{}` | `{ a: null, b: 123 }`
`{ b: 123 }` | `{}` | `{ b: 123 }`
`{ a: $var, b: 123 }` | `{ var: null }` | `{ a: null, b: 123 }`
`{ a: $var, b: 123 }` | `{}` | `{ b: 123 }`
`{ b: $var }` | `{ var: 123 }` | `{ b: 123 }`
`$var` | `{ var: { b: 123 } }` | `{ b: 123 }`
`"abc123"` | `{}` | Error: Incorrect value
-`$var` | `{ var: "abc123" } }` | Error: Incorrect value
+`$var` | `{ var: "abc123" }` | Error: Incorrect value
`{ a: "abc", b: "123" }` | `{}` | Error: Incorrect value for field {b}
`{ a: "abc" }` | `{}` | Error: Missing required field {b}
`{ b: $var }` | `{}` | Error: Missing required field {b}.
`$var` | `{ var: { a: "abc" } }` | Error: Missing required field {b}
`{ a: "abc", b: null }` | `{}` | Error: {b} must be non-null.
`{ b: $var }` | `{ var: null }` | Error: {b} must be non-null.
`{ b: 123, c: "xyz" }` | `{}` | Error: Unexpected field {c}
@@ -1412,89 +1638,95 @@ Literal Value | Variables | Coerced Value
1. An Input Object type must define one or more input fields.
2. For each input field of an Input Object type:
1. The input field must have a unique name within that Input Object type;
no two input fields may share the same name.
2. The input field must not have a name which begins with the
characters {"__"} (two underscores).
3. The input field must accept a type where {IsInputType(inputFieldType)}
returns {true}.
+3. If an Input Object references itself either directly or through referenced
+ Input Objects, at least one of the fields in the chain of references must be
+ either a nullable or a List type.
### Input Object Extensions
InputObjectTypeExtension :
- extend input Name Directives[Const]? InputFieldsDefinition
- - extend input Name Directives[Const]
+ - extend input Name Directives[Const] [lookahead != `{`]
Input object type extensions are used to represent an input object type which
has been extended from some original input object type. For example, this might
be used by a GraphQL service which is itself an extension of another GraphQL service.
**Type Validation**
Input object type extensions have the potential to be invalid if incorrectly defined.
1. The named type must already be defined and must be a Input Object type.
-3. All fields of an Input Object type extension must have unique names.
-4. All fields of an Input Object type extension must not already be a field of
+2. All fields of an Input Object type extension must have unique names.
+3. All fields of an Input Object type extension must not already be a field of
the original Input Object.
-5. Any directives provided must not already apply to the original Input Object type.
+4. Any non-repeatable directives provided must not already apply to the
+ original Input Object type.
## List
A GraphQL list is a special collection type which declares the type of each
item in the List (referred to as the *item type* of the list). List values are
serialized as ordered lists, where each item in the list is serialized as per
-the item type. To denote that a field uses a List type the item type is wrapped
-in square brackets like this: `pets: [Pet]`.
+the item type.
+
+To denote that a field uses a List type the item type is wrapped in square brackets
+like this: `pets: [Pet]`. Nesting lists is allowed: `matrix: [[Int]]`.
**Result Coercion**
-GraphQL servers must return an ordered list as the result of a list type. Each
+GraphQL services must return an ordered list as the result of a list type. Each
item in the list must be the result of a result coercion of the item type. If a
reasonable coercion is not possible it must raise a field error. In
particular, if a non-list is returned, the coercion should fail, as this
indicates a mismatch in expectations between the type system and the
implementation.
-If a list's item type is nullable, then errors occuring during preparation or
+If a list's item type is nullable, then errors occurring during preparation or
coercion of an individual item in the list must result in a the value {null} at
-that position in the list along with an error added to the response. If a list's
-item type is non-null, an error occuring at an individual item in the list must
-result in a field error for the entire list.
+that position in the list along with a field error added to the response.
+If a list's item type is non-null, a field error occurring at an individual item
+in the list must result in a field error for the entire list.
-Note: For more information on the error handling process, see "Errors and
-Non-Nullability" within the Execution section.
+Note: See [Handling Field Errors](#sec-Handling-Field-Errors) for more about
+this behavior.
**Input Coercion**
When expected as an input, list values are accepted only when each item in the
list can be accepted by the list's item type.
If the value passed as an input to a list type is *not* a list and not the
{null} value, then the result of input coercion is a list of size one,
where the single item value is the result of input coercion for the list's item
type on the provided value (note this may apply recursively for nested lists).
-This allow inputs which accept one or many arguments (sometimes referred to as
+This allows inputs which accept one or many arguments (sometimes referred to as
"var args") to declare their input type as a list while for the common case of a
single value, a client can just pass that value directly rather than
constructing the list.
Following are examples of input coercion with various list types and values:
Expected Type | Provided Value | Coerced Value
------------- | ---------------- | ---------------------------
`[Int]` | `[1, 2, 3]` | `[1, 2, 3]`
`[Int]` | `[1, "b", true]` | Error: Incorrect item value
`[Int]` | `1` | `[1]`
`[Int]` | `null` | `null`
-`[[Int]]` | `[[1], [2, 3]]` | `[[1], [2, 3]`
+`[[Int]]` | `[[1], [2, 3]]` | `[[1], [2, 3]]`
`[[Int]]` | `[1, 2, 3]` | Error: Incorrect item value
`[[Int]]` | `1` | `[[1]]`
`[[Int]]` | `null` | `null`
## Non-Null
By default, all types in GraphQL are nullable; the {null} value is a valid
@@ -1502,43 +1734,43 @@ response for all of the above types. To declare a type that disallows null,
the GraphQL Non-Null type can be used. This type wraps an underlying type,
and this type acts identically to that wrapped type, with the exception
that {null} is not a valid response for the wrapping type. A trailing
exclamation mark is used to denote a field that uses a Non-Null type like this:
`name: String!`.
**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},
it also does not accept omission. For the sake of simplicity nullable types
are always optional and non-null types are always required.
**Result Coercion**
In all of the above result coercions, {null} was considered a valid value.
To coerce the result of a Non-Null type, the coercion of the wrapped type
should be performed. If that result was not {null}, then the result of coercing
the Non-Null type is that result. If that result was {null}, then a field error
must be raised.
-Note: When a field error is raised on a non-null value, the error propogates to
+Note: When a field error is raised on a non-null value, the error propagates to
the parent field. For more informatio
gitextract_yl1f9z0u/
├── .github/
│ ├── ISSUE_TEMPLATE.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── algorithm-format-check.mjs
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .prettierignore
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── STYLE_GUIDE.md
├── build.sh
├── changelogs/
│ ├── October2021.md
│ └── September2025.md
├── cspell.yml
├── package.json
├── scripts/
│ ├── generate-contributor-list.mjs
│ └── update-appendix-specified-definitions.mjs
├── signed-agreements/
│ └── README.md
└── spec/
├── Appendix A -- Conformance.md
├── Appendix B -- Notation Conventions.md
├── Appendix C -- Grammar Summary.md
├── Appendix D -- Specified Definitions.md
├── GraphQL.md
├── Section 1 -- Overview.md
├── Section 2 -- Language.md
├── Section 3 -- Type System.md
├── Section 4 -- Introspection.md
├── Section 5 -- Validation.md
├── Section 6 -- Execution.md
├── Section 7 -- Response.md
└── metadata.json
SYMBOL INDEX (25 symbols across 3 files)
FILE: .github/algorithm-format-check.mjs
constant SPEC_DIR (line 3) | const SPEC_DIR = new URL("../spec", import.meta.url).pathname;
FILE: scripts/generate-contributor-list.mjs
constant RAW_ARGS (line 5) | const RAW_ARGS = process.argv.slice(2);
constant DEBUG (line 6) | const DEBUG = RAW_ARGS.includes("--debug");
function die (line 13) | function die(msg, code = 1) { console.error(msg); process.exit(code) }
function normalizeName (line 15) | function normalizeName(s) {
function pickBetterName (line 23) | function pickBetterName(current, candidate) {
function sanitizeDisplayName (line 33) | function sanitizeDisplayName(raw, fallback) {
function parseArgs (line 42) | function parseArgs() {
function execGit (line 49) | function execGit(argv, opts = {}) {
function repoNameWithOwner (line 56) | function repoNameWithOwner() {
function revList (line 63) | function revList(range, paths) {
function parseCoAuthorLines (line 69) | function parseCoAuthorLines(message) {
function loginFromNoreply (line 76) | function loginFromNoreply(email) {
function candidateHandlesFromEmailAndName (line 80) | function candidateHandlesFromEmailAndName(email, name) {
constant REPO (line 111) | const REPO = repoNameWithOwner();
function getToken (line 113) | function getToken() {
constant TOKEN (line 118) | const TOKEN = getToken();
function graphql (line 121) | async function graphql(query, variables) {
function fetchCommitsByOidBatch (line 154) | async function fetchCommitsByOidBatch(oids) {
function searchUsersByNameExact (line 188) | async function searchUsersByNameExact(name) {
function searchUsersByLoginToken (line 201) | async function searchUsersByLoginToken(token) {
function fetchProfileNames (line 209) | async function fetchProfileNames(logins) {
function main (line 227) | async function main() {
FILE: scripts/update-appendix-specified-definitions.mjs
function stripDescriptions (line 14) | function stripDescriptions(sdl) {
function printSpecifiedScalars (line 28) | function printSpecifiedScalars() {
Condensed preview — 31 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (701K chars).
[
{
"path": ".github/ISSUE_TEMPLATE.md",
"chars": 566,
"preview": "!!! IMPORTANT !!!\n\nBefore creating your issue:\n\n- Have a question? Find community resources at https://graphql.org/commu"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 131,
"preview": "!!! IMPORTANT !!!\n\nPlease Read https://github.com/graphql/graphql-spec/blob/master/CONTRIBUTING.md\nbefore creating a Pul"
},
{
"path": ".github/algorithm-format-check.mjs",
"chars": 7904,
"preview": "import { readFile, readdir } from \"node:fs/promises\";\n\nconst SPEC_DIR = new URL(\"../spec\", import.meta.url).pathname;\n\n/"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1245,
"preview": "name: CI\n\non:\n push:\n branches:\n - main\n pull_request:\n\njobs:\n test-spelling:\n runs-on: ubuntu-latest\n "
},
{
"path": ".gitignore",
"chars": 89,
"preview": "*.swp\n*~\n.*.haste_cache.*\n.DS_Store\nnpm-debug.log\n/build\n/public\n/gh-pages\n/node_modules\n"
},
{
"path": ".prettierignore",
"chars": 112,
"preview": "*.swp\n*~\n.*.haste_cache.*\n.DS_Store\nnpm-debug.log\n/build\n/changelogs\n/out\n/gh-pages\n/node_modules\n/package.json\n"
},
{
"path": "CONTRIBUTING.md",
"chars": 11601,
"preview": "# GraphQL Specification Contribution Guide\n\nGraphQL is still an evolving language. This repository contains the\nspecific"
},
{
"path": "LICENSE.md",
"chars": 2385,
"preview": "# Appendix: Copyright and Licensing\n\nThe GraphQL Specification Project is made available by the\n[Joint Development Found"
},
{
"path": "README.md",
"chars": 29093,
"preview": "[](https://graphql.org/)\n\n# GraphQL\n\n<img alt=\"GraphQL Logo\" a"
},
{
"path": "STYLE_GUIDE.md",
"chars": 4499,
"preview": "**This document is a work in progress.**\n\n# GraphQL Specification Style Guide\n\nThis document outlines the styles used in"
},
{
"path": "build.sh",
"chars": 2839,
"preview": "#!/bin/bash -e\n# This script publishes the GraphQL specification document to the web.\n\n# Determine if this is a tagged r"
},
{
"path": "changelogs/October2021.md",
"chars": 269877,
"preview": "# October2021 Changelog\n\nThis describes the set of changes since the last edition of the GraphQL\nspecification, [June201"
},
{
"path": "changelogs/September2025.md",
"chars": 44331,
"preview": "# September 2025 Changelog\n\nThis describes the set of changes since the last edition of the GraphQL\nspecification, [Octo"
},
{
"path": "cspell.yml",
"chars": 453,
"preview": "language: en-US\nignoreRegExpList:\n # Posessives\n - /[a-z]{2,}'s/\nwords:\n # Terms of art\n - endianness\n - interopera"
},
{
"path": "package.json",
"chars": 1460,
"preview": "{\n \"name\": \"graphql-spec\",\n \"private\": true,\n \"contributors\": [\n \"Lee Byron <lee@leebyron.com> (http://leebyron.co"
},
{
"path": "scripts/generate-contributor-list.mjs",
"chars": 12555,
"preview": "import { execFileSync } from \"node:child_process\";\nimport https from \"node:https\";\n\n// ---------- flags / utils\nconst RA"
},
{
"path": "scripts/update-appendix-specified-definitions.mjs",
"chars": 1281,
"preview": "import prettier from \"prettier\";\nimport { writeFile } from \"node:fs/promises\";\nimport {\n printIntrospectionSchema,\n bu"
},
{
"path": "signed-agreements/README.md",
"chars": 590,
"preview": "# Legacy Signed Agreements\n\nThe signed agreement found in this directory was contributed when this\nspecification was lic"
},
{
"path": "spec/Appendix A -- Conformance.md",
"chars": 2706,
"preview": "# A. Appendix: Conformance\n\nA conforming implementation of GraphQL must fulfill all normative requirements.\nConformance "
},
{
"path": "spec/Appendix B -- Notation Conventions.md",
"chars": 8481,
"preview": "# B. Appendix: Notation Conventions\n\nThis specification document contains a number of notation conventions used to\ndescr"
},
{
"path": "spec/Appendix C -- Grammar Summary.md",
"chars": 8699,
"preview": "# C. Appendix: Grammar Summary\n\n## Source Text\n\nSourceCharacter :: \"Any Unicode scalar value\"\n\n## Ignored Tokens\n\nIgnore"
},
{
"path": "spec/Appendix D -- Specified Definitions.md",
"chars": 2240,
"preview": "# D. Appendix: Type System Definitions\n\nThis appendix lists all type system definitions specified in this document.\n\nThe"
},
{
"path": "spec/GraphQL.md",
"chars": 2624,
"preview": "# GraphQL\n\n_Current Working Draft_\n\n**Introduction**\n\nThis is the specification for GraphQL, a query language and execut"
},
{
"path": "spec/Section 1 -- Overview.md",
"chars": 3987,
"preview": "# Overview\n\nGraphQL is a query language designed to build client applications by providing\nan intuitive and flexible syn"
},
{
"path": "spec/Section 2 -- Language.md",
"chars": 48632,
"preview": "# Language\n\nClients use the GraphQL query language to make requests to a GraphQL service. We\nrefer to these _request_ so"
},
{
"path": "spec/Section 3 -- Type System.md",
"chars": 81291,
"preview": "# Type System\n\nThe GraphQL Type system describes the capabilities of a GraphQL service and is\nused to determine if a req"
},
{
"path": "spec/Section 4 -- Introspection.md",
"chars": 15793,
"preview": "# Introspection\n\nA GraphQL service supports introspection over its schema. This schema is queried\nusing GraphQL itself, "
},
{
"path": "spec/Section 5 -- Validation.md",
"chars": 56232,
"preview": "# Validation\n\nA GraphQL service does not just verify if a request is syntactically correct,\nbut also ensures that it is "
},
{
"path": "spec/Section 6 -- Execution.md",
"chars": 40411,
"preview": "# Execution\n\nA GraphQL service generates a response from a request via execution.\n\n:: A _request_ for execution consists"
},
{
"path": "spec/Section 7 -- Response.md",
"chars": 15140,
"preview": "# Response\n\nWhen a GraphQL service receives a _request_, it must return a well-formed\nresponse. The service's response d"
},
{
"path": "spec/metadata.json",
"chars": 518,
"preview": "{\n \"biblio\": {\n \"https://www.unicode.org/glossary\": {\n \"byte-order-mark\": \"#byte_order_mark\",\n \"leading-su"
}
]
About this extraction
This page contains the full source code of the graphql/graphql-spec GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 31 files (661.9 KB), approximately 162.0k tokens, and a symbol index with 25 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.