中文版GraphQL标准

中文版GraphQL标准

title: 中文版GraphQL标准 date: 2015-07-29 16:52:33 updated : permalink: tags:

  • API
  • GraphQL categories:
  • API
  • 译文

GraphQL

Working Draft – July 2015

Introduction

This is a Draft RFC Specification for GraphQL, a query language created by Facebook in 2012 for describing the capabilities and requirements of data models for client‐server applications. The development of this standard started in 2015. GraphQL is a new and evolving language and is not complete. Significant enhancement will continue in future editions of this specification.

Copyright notice

Copyright (c) 2015, Facebook, Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  1. 1Overview
  2. 2Language
    1. 2.1Source Text
      1. 2.1.1White Space
      2. 2.1.2Line Terminators
      3. 2.1.3Comments
      4. 2.1.4Insignificant Commas
      5. 2.1.5Lexical Tokens
      6. 2.1.6Ignored Tokens
      7. 2.1.7Punctuators
      8. 2.1.8Names
    2. 2.2Query Document
      1. 2.2.1Operations
      2. 2.2.2Selection Sets
      3. 2.2.3Fields
      4. 2.2.4Arguments
      5. 2.2.5Field Alias
      6. 2.2.6Fragments
        1. 2.2.6.1Type Conditions
        2. 2.2.6.2Inline Fragments
      7. 2.2.7Input Values
        1. 2.2.7.1Int Value
        2. 2.2.7.2Float Value
        3. 2.2.7.3Boolean Value
        4. 2.2.7.4String Value
        5. 2.2.7.5Enum Value
        6. 2.2.7.6List Value
        7. 2.2.7.7Input Object Values
      8. 2.2.8Variables
        1. 2.2.8.1Variable use within Fragments
      9. 2.2.9Input Types
      10. 2.2.10Directives 1. 2.2.10.1Fragment Directives
  3. 3Type System
    1. 3.1Types
      1. 3.1.1Scalars
        1. 3.1.1.1Built-in Scalars
          1. 3.1.1.1.1Int
          2. 3.1.1.1.2Float
          3. 3.1.1.1.3String
          4. 3.1.1.1.4Boolean
          5. 3.1.1.1.5ID
      2. 3.1.2Objects
        1. 3.1.2.1Object Field Arguments
        2. 3.1.2.2Object Field deprecation
        3. 3.1.2.3Object type validation
      3. 3.1.3Interfaces
        1. 3.1.3.1Interface type validation
      4. 3.1.4Unions
        1. 3.1.4.1Union type validation
      5. 3.1.5Enums
      6. 3.1.6Input Objects
      7. 3.1.7Lists
      8. 3.1.8Non-Null
    2. 3.2Directives
      1. 3.2.1@skip
      2. 3.2.2@include
    3. 3.3Starting types
  4. 4Introspection
    1. 4.1General Principles
      1. 4.1.1Naming conventions
      2. 4.1.2Documentation
      3. 4.1.3Deprecation
      4. 4.1.4Type Name Introspection
    2. 4.2Schema Introspection
      1. 4.2.1The “__Type” Type
      2. 4.2.2Type Kinds
        1. 4.2.2.1Scalar
        2. 4.2.2.2Object
        3. 4.2.2.3Union
        4. 4.2.2.4Interface
        5. 4.2.2.5Enum
        6. 4.2.2.6Input Object
        7. 4.2.2.7List
        8. 4.2.2.8Non-null
        9. 4.2.2.9Combining List and Non-Null
  5. 5Validation
    1. 5.1Fields
      1. 5.1.1Field Selections on Objects, Interfaces, and Unions Types
      2. 5.1.2Field Selection Merging
      3. 5.1.3Leaf Field Selections
    2. 5.2Arguments
      1. 5.2.1Argument Names
      2. 5.2.2Argument Values Type Correctness
        1. 5.2.2.1Compatible Values
        2. 5.2.2.2Required Arguments
    3. 5.3Fragments
      1. 5.3.1Fragment Declarations
        1. 5.3.1.1Fragment Spread Type Existence
        2. 5.3.1.2Fragments On Composite Types
        3. 5.3.1.3Fragments Must Be Used
      2. 5.3.2Fragment Spreads
        1. 5.3.2.1Fragment spread target defined
        2. 5.3.2.2Fragment spreads must not form cycles
        3. 5.3.2.3Fragment spread is possible
          1. 5.3.2.3.1Object Spreads In Object Scope
          2. 5.3.2.3.2Abstract Spreads in Object Scope
          3. 5.3.2.3.3Object Spreads In Abstract Scope
          4. 5.3.2.3.4Abstract Spreads in Abstract Scope
    4. 5.4Directives
      1. 5.4.1Directives Are Defined
    5. 5.5Operations
      1. 5.5.1Variables
        1. 5.5.1.1Variable Default Values Are Correctly Typed
        2. 5.5.1.2Variables Are Input Types
        3. 5.5.1.3All Variable Uses Defined
        4. 5.5.1.4All Variables Used
        5. 5.5.1.5All Variable Usages are Allowed
  6. 6Execution
    1. 6.1Evaluating requests
    2. 6.2Evaluating operations
    3. 6.3Evaluating selection sets
    4. 6.4Evaluating a grouped field set
      1. 6.4.1Field entries
      2. 6.4.2Normal evaluation
      3. 6.4.3Serial execution
      4. 6.4.4Error handling
      5. 6.4.5Nullability
  7. 7Response
    1. 7.1Serialization Format
      1. 7.1.1JSON Serialization
    2. 7.2Response Format
      1. 7.2.1Data
      2. 7.2.2Errors
  8. AAppendix: Notation Conventions
    1. A.1Context-Free Grammar
    2. A.2Lexical and Syntactical Grammar
    3. A.3Grammar Notation
    4. A.4Grammar Semantics
    5. A.5Algorithms
  9. BAppendix: Grammar Summary
    1. B.1Ignored Tokens
    2. B.2Lexical Tokens
    3. B.3Query Document

1Overview

GraphQL is a query language designed to build client applications by providing an intuitive and flexible syntax and system for describing their data requirements and interactions.

For example, this GraphQL request will receive the name of the user with id 4 from the Facebook implementation of GraphQL.

{
  user(id: 4) {
    name
  }
}

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 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 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 build 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 and nature of the response.
  • Client‐specified queries: Through its type system, a GraphQL server 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.
  • Introspective: GraphQL is introspective. A GraphQL server’s type system must 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 little or no formal training. To enable that experience, there must be those that build those servers 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 has yet to be built. We look forward to working with the community in order to do that.

2Language

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 and mutations are both operations) as well as fragments, a common unit of composition allowing for query 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 ::).

2.1Source Text

[SourceCharacter](#SourceCharacter)
Any Unicode character

GraphQL documents are expressed as a sequence of Unicode characters. However, with few exceptions, most of GraphQL is expressed only in the original ASCII range so as to be as widely compatible with as many existing tools, languages, and serialization formats as possible. Other than within comments, Non‐ASCII Unicode characters are only found within StringValue.

2.1.1White Space

[WhiteSpace](#WhiteSpace)
Horizontal Tab (U+0009)
Vertical Tab (U+000B)
Form Feed (U+000C)
Space (U+0020)
No-break Space (U+00A0)

White space is used to improve legibility of source text and act as separation between tokens, and any amount of white space may appear before or after any token. White space between tokens is not significant to the semantic meaning of a GraphQL query document, however white space characters may appear within a String or Comment token.

2.1.2Line Terminators

[LineTerminator](#LineTerminator)
New Line (U+000A)
Carriage Return (U+000D)
Line Separator (U+2028)
Paragraph Separator (U+2029)

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 query document. Line terminators are not found within any other token.

2.1.3Comments

[Comment](#Comment)
#[CommentChar](#CommentChar)listopt
[CommentChar](#CommentChar)
[SourceCharacter](#SourceCharacter)[LineTerminator](#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.

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 GraphQL query document.

2.1.4Insignificant Commas

[Comma](#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 query 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 often desired for legibility and maintainability of source code.

2.1.5Lexical Tokens

[Token](#Token)
[Punctuator](#Punctuator)
[Name](#Name)
[IntValue](#IntValue)
[FloatValue](#FloatValue)
[StringValue](#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.

Tokens are later used as terminal symbols in a GraphQL query document syntactic grammars.

2.1.6Ignored Tokens

[Ignored](#Ignored)
[WhiteSpace](#WhiteSpace)
[LineTerminator](#LineTerminator)
[Comment](#Comment)
[Comma](#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.

No characters are ignored while parsing a given token, as an example no white space characters are permitted between the characters defining a FloatValue.

2.1.7Punctuators

[Punctuator](#Punctuator)

| ! | $ | ( | ) | | : | = | @ | [ | ] | { | } |

GraphQL documents include punctuation in order to describe structure. GraphQL is a data description language and not a programming language, therefore GraphQL lacks the punctionation often used to describe mathematical expressions.

2.1.8Names

[Name](#Name)
/[_A-Za-z][_0-9A-Za-z]*/

GraphQL query documents are full of named things: operations, fields, arguments, 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 ASCII subset of possible characters to support interoperation with as many other systems as possible.

2.2Query Document

[Document](#Document)
[Definition](#Definition)list
[Definition](#Definition)
[OperationDefinition](#OperationDefinition)
[FragmentDefinition](#FragmentDefinition)

A GraphQL query document describes a complete file or request string received by a GraphQL service. A document contains multiple definitions of Operations and Fragments. GraphQL query documents are only executable by a server if they contain an operation. However documents which do not contain operations may still be parsed and validated to allow client to represent a single request across many documents.

If a query document contains only one query operation, that operation may be represented in the shorthand form, which omits the query keyword and operation name. Otherwise, if a GraphQL query document contains multiple operations, each operation must be named. When submitting a query document with multiple operations to a GraphQL service, the name of the desired operation to be executed must also be provided.

2.2.1Operations

[OperationDefinition](#OperationDefinition)
[OperationType](#OperationType)[Name](#Name)[VariableDefinitions](#VariableDefinitions)opt[Directives](#Directives)opt[SelectionSet](#SelectionSet)
[SelectionSet](#SelectionSet)
[OperationType](#OperationType)

| query | mutation |

There are two types of operations that GraphQL models:

  • query – a read‐only fetch.
  • mutation – a write followed by a fetch.

Each operation is represented by an operation name and a selection set.

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.

For example, this unnamed query operation is written via query shorthand.

{
  field
}
many examples below will use the query short‐hand syntax.

2.2.2Selection Sets

[SelectionSet](#SelectionSet)
{[Selection](#Selection)list}
[Selection](#Selection)
[Field](#Field)
[FragmentSpread](#FragmentSpread)
[InlineFragment](#InlineFragment)

An operation selects the set of information it needs, and will receive exactly that information and nothing more, avoiding over‐fetching and under‐fetching data.

{
  id
  firstName
  lastName
}

In this query, the id, firstName, and lastName fields form a selection set. Selection sets may also contain fragment references.

2.2.3Fields

[Field](#Field)
[Alias](#Alias)opt[Name](#Name)[Arguments](#Arguments)opt[Directives](#Directives)opt[SelectionSet](#SelectionSet)opt

A selection set is primarily composed of fields. A field describes one discrete piece of information available to request within a selection set.

Some fields describe complex data or relationships to other data. In order to further explore this data, a field may itself contain a selection set, allowing for deeply nested requests. All GraphQL operations must specify their selections down to fields which return scalar values to ensure an unambiguosly shaped response.

For example, this operation selects fields of complex data and relationships down to scalar values.

{
  me {
    id
    firstName
    lastName
    birthday {
      month
      day
    }
    friends {
      name
    }
  }
}

Fields in the top‐level selection set of an operation often represent some information that is globally accessible to your application and its current viewer. Some typical examples of these top fields include references to a current logged‐in viewer, or accessing certain types of data referenced by a unique identifier.

# `me` could represent the currently logged in viewer.
{
  me {
    name
  }
}

# `user` represents one of many users in a graph of data, referred to by a
# unique identifier.
{
  user(id: 4) {
    name
  }
}

2.2.4Arguments

[Arguments](#Arguments)
([Argument](#Argument)list)
[Argument](#Argument)
[Name](#Name):[Value](#Value)

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.

In this example, we want to query a specific user (requested via the id argument) and their profile picture of a specific size:

{
  user(id: 4) {
    id
    name
    profilePic(size: 100)
  }
}

Many arguments can exist for a given field:

{
  user(id: 4) {
    id
    name
    profilePic(width: 100, height: 50)
  }
}

Arguments are unordered

Arguments may be provided in any syntactic order and maintain identical semantic meaning.

These two queries are semantically identical:

{
  picture(width: 200, height: 100)
}
{
  picture(height: 100, width: 200)
}

2.2.5Field Alias

[Alias](#Alias)
[Name](#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.

In this example, we can fetch two profile pictures of different sizes and ensure the resulting object will not have duplicate keys:

{
  user(id: 4) {
    id
    name
    smallPic: profilePic(size: 64)
    bigPic: profilePic(size: 1024)
  }
}

Which returns the result:

{
  "user": {
    "id": 4,
    "name": "Mark",
    "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:

{
  zuck: user(id: 4) {
    id
    name
  }
}

Returns the result:

{
  "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.

2.2.6Fragments

[FragmentSpread](#FragmentSpread)
...[FragmentName](#FragmentName)[Directives](#Directives)opt
[FragmentDefinition](#FragmentDefinition)
fragment[FragmentName](#FragmentName)on[TypeCondition](#TypeCondition)[Directives](#Directives)opt[SelectionSet](#SelectionSet)
[FragmentName](#FragmentName)
[Name](#Name)on

Fragments are the primary unit of composition in GraphQL.

Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document. Inline Fragments can be used directly within a selection to condition upon a type condition when querying against an interface or union.

For example, if we wanted to fetch some common information about mutual friends as well as friends of some user:

query noFragments {
  user(id: 4) {
    friends(first: 10) {
      id
      name
      profilePic(size: 50)
    }
    mutualFriends(first: 10) {
      id
      name
      profilePic(size: 50)
    }
  }
}

The repeated fields could be extracted into a fragment and composed by a parent fragment or query.

query withFragments {
  user(id: 4) {
    friends(first: 10) {
      ...friendFields
    }
    mutualFriends(first: 10) {
      ...friendFields
    }
  }
}

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 as the fragment invocation. This happens through multiple levels of fragment spreads.

For example:

query withNestedFragments {
  user(id: 4) {
    friends(first: 10) {
      ...friendFields
    }
    mutualFriends(first: 10) {
      ...friendFields
    }
  }
}

fragment friendFields on User {
  id
  name
  ...standardProfilePic
}

fragment standardProfilePic on User {
  profilePic(size: 50)
}

The queries noFragments, withFragments, and withNestedFragments all produce the same response object.

2.2.6.1Type Conditions
[TypeCondition](#TypeCondition)
[NamedType](#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 it is operating on matches the type of the fragment.

For example in this query on the Facebook data model:

query FragmentTyping {
  profiles(handles: ["zuck", "cocacola"]) {
    handle
    ...userFragment
    ...pageFragment
  }
}

fragment userFragment on User {
  friends {
    count
  }
}

fragment pageFragment on Page {
  likers {
    count
  }
}

The profiles root field returns a list where each element could be a Page or a User. When the object in the profiles result is a User, friends will be present and likers will not. Conversely when the result is a Page, likers will be present and friends will not.

{
  "profiles" : [
    {
      "handle" : "zuck",
      "friends" : { "count" : 1234 }
    },
    {
      "handle" : "cocacola",
      "likers" : { "count" : 90234512 }
    }
  ]
}
2.2.6.2Inline Fragments
[InlineFragment](#InlineFragment)
...on[TypeCondition](#TypeCondition)[Directives](#Directives)opt[SelectionSet](#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.

query inlineFragmentTyping {
  profiles(handles: ["zuck", "cocacola"]) {
    handle
    ... on User {
      friends {
        count
      }
    }
    ... on Page {
      likers {
        count
      }
    }
  }
}

2.2.7Input Values

[Value](#Value)Const
Const[Variable](#Variable)
[IntValue](#IntValue)
[FloatValue](#FloatValue)
[StringValue](#StringValue)
[BooleanValue](#BooleanValue)
[EnumValue](#EnumValue)
[ListValue](#ListValue)Const
[ObjectValue](#ObjectValue)Const

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).

2.2.7.1Int Value
[IntValue](#IntValue)
[IntegerPart](#IntegerPart)
[IntegerPart](#IntegerPart)
[NegativeSign](#NegativeSign)opt0
[NegativeSign](#NegativeSign)opt[NonZeroDigit](#NonZeroDigit)[Digit](#Digit)listopt
[NegativeSign](#NegativeSign)
-
[Digit](#Digit)

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

[NonZeroDigit](#NonZeroDigit)
[Digit](#Digit)0

An Int number is specified without a decimal point or exponent (ex. 1).

2.2.7.2Float Value
[FloatValue](#FloatValue)
[IntegerPart](#IntegerPart)[FractionalPart](#FractionalPart)
[IntegerPart](#IntegerPart)[ExponentPart](#ExponentPart)
[IntegerPart](#IntegerPart)[FractionalPart](#FractionalPart)[ExponentPart](#ExponentPart)
[FractionalPart](#FractionalPart)
.[Digit](#Digit)list
[ExponentPart](#ExponentPart)
[ExponentIndicator](#ExponentIndicator)[Sign](#Sign)opt[Digit](#Digit)list
[ExponentIndicator](#ExponentIndicator)

| e | E |

[Sign](#Sign)

| + | - |

A Float number includes either a decimal point (ex. 1.0) or an exponent (ex. 1e50) or both (ex. 6.0221413e23).

2.2.7.3Boolean Value
[BooleanValue](#BooleanValue)

| true | false |

The two keywords true and false represent the two boolean values.

2.2.7.4String Value
[StringValue](#StringValue)
""
"[StringCharacter](#StringCharacter)list"
[StringCharacter](#StringCharacter)
[SourceCharacter](#SourceCharacter)"\[LineTerminator](#LineTerminator)
\[EscapedUnicode](#EscapedUnicode)
\[EscapedCharacter](#EscapedCharacter)
[EscapedUnicode](#EscapedUnicode)
u/[0-9A-Fa-f]{4}/
[EscapedCharacter](#EscapedCharacter)

| | </span> | / | b | f | n | r | t |

Strings are lists of characters wrapped in double‐quotes ". (ex. "Hello World"). White space and other otherwise‐ignored characters are significant within a string value.

2.2.7.5Enum Value
[EnumValue](#EnumValue)
[Name](#Name)truefalsenull

Enum values are represented as unquoted names (ex. MOBILE_WEB). It is recommended that Enum values be “all caps”. Enum values are only used in contexts where the precise enumeration type is known. Therefore it’s not necessary to supply an enumeration type name in the literal.

An enum value cannot be “null” in order to avoid confusion. GraphQL does not supply a value literal to represent the concept null.

2.2.7.6List Value
[ListValue](#ListValue)Const
[]
[[Value](#Value)Constlist]

Lists are ordered sequences of values wrapped in square‐brackets [ ]. The values of a List literal may be any value literal or variable (ex. [1, 2, 3]).

Commas are optional throughout GraphQL so trailing commas are allowed and repeated commas do not represent missing values.

Semantics

[ListValue](#ListValue)
[]
  1. Return a new empty list value.
[ListValue](#ListValue)
[[Value](#Value)list]
  1. Let inputList be a new empty list value.
  2. For each Valuelist
    1. Let value be the result of evaluating Value.
    2. Append value to inputList.
  3. Return inputList
2.2.7.7Input Object Values
[ObjectValue](#ObjectValue)Const
{}
{[ObjectField](#ObjectField)Constlist}
[ObjectField](#ObjectField)Const
[Name](#Name):[Value](#Value)Const

Input object literal values are unordered lists of keyed input values wrapped in 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.”

Semantics

[ObjectValue](#ObjectValue)
{}
  1. Return a new input object value with no fields.
[ObjectValue](#ObjectValue)
{[ObjectField](#ObjectField)list}
  1. Let inputObject be a new input object value with no fields.
  2. For each field in ObjectFieldlist
    1. Let name be Name in field.
    2. If inputObject contains a field named name throw Syntax Error.
    3. Let value be the result of evaluating Value in field.
    4. Add a field to inputObject of name name containing value value.
  3. Return inputObject

2.2.8Variables

[Variable](#Variable)
$[Name](#Name)
[VariableDefinitions](#VariableDefinitions)
([VariableDefinition](#VariableDefinition)list)
[VariableDefinition](#VariableDefinition)
[Variable](#Variable):[Type](#Type)[DefaultValue](#DefaultValue)opt
[DefaultValue](#DefaultValue)
=[Value](#Value)Const

A GraphQL query can be parameterized with variables, maximizing query 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.

In this example, we want to fetch a profile picture size based on the size of a particular device:

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:

{
  "devicePicSize": 60
}
2.2.8.1Variable 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.

2.2.9Input Types

[Type](#Type)
[NamedType](#NamedType)
[ListType](#ListType)
[NonNullType](#NonNullType)
[NamedType](#NamedType)
[Name](#Name)
[ListType](#ListType)
[[Type](#Type)]
[NonNullType](#NonNullType)
[NamedType](#NamedType)!
[ListType](#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.

Semantics

[Type](#Type)
[Name](#Name)
  1. Let name be the string value of Name
  2. Let type be the type defined in the Schema named name
  3. type must not be null
  4. Return type
[Type](#Type)
[[Type](#Type)]
  1. Let itemType be the result of evaluating Type
  2. Let type be a List type where itemType is the contained type.
  3. Return type
[Type](#Type)
[Type](#Type)!
  1. Let nullableType be the result of evaluating Type
  2. Let type be a Non‐Null type where nullableType is the contained type.
  3. Return type

2.2.10Directives

[Directives](#Directives)
[Directive](#Directive)list
[Directive](#Directive)
@[Name](#Name)[Arguments](#Arguments)opt

Directives provide a way to describe alternate runtime execution and type 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 fields, fragments, and operations.

As future versions of GraphQL adopts new configurable execution capabilities, they may be exposed via directives.

2.2.10.1Fragment Directives

Fragments may include directives to alter their behavior. At runtime, the directives provided on a fragment spread override those described on the definition.

For example, the following query:

query hasConditionalFragment($condition: Boolean) {
  ...maybeFragment @include(if: $condition)
}

fragment maybeFragment on Query {
  me {
    name
  }
}

Will have identical runtime behavior as

query hasConditionalFragment($condition: Boolean) {
  ...maybeFragment
}

fragment maybeFragment on Query @include(if: $condition) {
  me {
    name
  }
}
[FragmentSpreadDirectives](#FragmentSpreadDirectives())(fragmentSpread)
  1. Let directives be the set of directives on fragmentSpread
  2. Let fragmentDefinition be the FragmentDefinition in the document named fragmentSpread refers to.
  3. For each directive in directives on fragmentDefinition
    1. If directives does not contain a directive named directive.
    2. Add directive into directives
  4. Return directives

3Type 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.

A GraphQL server’s capabilities are referred to as that server’s “schema”. A schema is defined in terms of the types and directives it supports.

A given GraphQL schema must itself be internally valid. This section describes the rules for this validation process where relevant.

A GraphQL schema is represented by a root type for each kind of operation: query and mutation; this determines the place in the type system where those operations begin.

All types within a GraphQL schema must have unique names. No two provided types may have the same name. No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).

All directives within a GraphQL schema must have unique names. A directive and a type may share the same name, since there is no ambiguity between them.

3.1Types

The fundamental unit of any GraphQL Schema is the type. There are eight kinds of types in GraphQL.

The most basic type is a Scalar. A scalar represents a primitive value, like a string or an integer. Oftentimes, the possible responses for a scalar field 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.

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.

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. The type system might want to define that it returns a list of other types; the List type is provided for this reason, and wraps another type. Similarly, the Non-Null type wraps another type, and denotes that the result will never be null. These two types are referred to as “wrapping types”; non‐wrapping types are referred to as “base types”. A wrapping type has an underlying “base type”, found by continually unwrapping the type until a base type is found.

Finally, oftentimes it is useful to provide complex structs as inputs to GraphQL queries; the Input Object type allows the schema to define exactly what data is expected from the client in these queries.

3.1.1Scalars

As expected by the name, a scalar represents a primitive value in GraphQL. 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.

Result Coercion

A GraphQL server, when preparing a field of a given scalar type, must uphold the contract the scalar type describes, either by coercing the value or producing an error.

For example, a GraphQL server could be preparing a field with the scalar type Int and encounter a floating‐point number. Since the server must not break the contract by yielding a non‐integer, the server should truncate the fractional value and only yield the integer value. If the server encountered a boolean true value, it should return 1. If the server encountered a string, it may attempt to parse the string for a base‐10 integer value. If the server encounters some value that cannot be reasonably coerced to an Int, then it must raise a field error.

Since this coercion behavior is not observable to clients of the GraphQL server, 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 Scalar type.

Input Coercion

If a GraphQL server 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.

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

3.1.1.1Built-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.

3.1.1.1.1Int

The Int scalar type represents a signed 32‐bit numeric non‐fractional values. Response formats that support a 32‐bit integer or a number type should use that type to represent this scalar.

Result Coercion

GraphQL servers should coerce non‐int raw values to Int when possible otherwise they must raise a field error. Examples of this may include returning 1 for the floating‐point number 1.0, or 2 for the string "2".

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 error indicating an incorrect type. If the integer input value represents a value less than -231 or greater than or equal to 231, a query error should be raised.

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.
3.1.1.1.2Float

The Float scalar type represents signed double‐precision fractional values as specified by IEEE 754. Response formats that support an appropriate double‐precision number type should use that type to represent this scalar.

Result Coercion

GraphQL servers should coerce non‐floating‐point raw values to Float when possible otherwise they must raise a field error. Examples of this may include returning 1.0 for the integer number 1, or 2.0 for the string "2".

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.

3.1.1.1.3String

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.

Result Coercion

GraphQL servers should coerce non‐string raw values to String when possible 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 incorrect type.

3.1.1.1.4Boolean

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

GraphQL servers should coerce non‐boolean raw values to Boolean when possible otherwise they must raise a field error. Examples of this may include returning true for any non‐zero number.

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.

3.1.1.1.5ID

The ID scalar type represents a unique identifier, often used to refetch an object or as 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.

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.

GraphQL servers 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.

3.1.2Objects

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 Objects represent a list of named fields, each of which yield a value of a specific type. Object values are serialized as unordered maps, where the queried field names (or aliases) are the keys and the result of evaluating the field is the value.

For example, a type Person could be described as:

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 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 unordered map containing exactly the subset of the object queried. Only fields that are declared on the object type may validly be queried on that object.

For example, selecting all the fields of Person:

{
  name
  age
  picture
}

Would yield the object:

{
  "name": "Mark Zuckerberg",
  "age": 30,
  "picture": "http://some.cdn/picture.jpg"
}

While selecting a subset of fields:

{
  name
  age
}

Must only yield exactly that subset:

{
  "name": "Mark Zuckerberg",
  "age": 30
}

A field of an Object type may be a Scalar, Enum, another Object type, an Interface, or a Union. Additionally, it may be any wrapping type whose underlying base type is one of those five.

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:

{
  name
  relationship
}

However, this example is valid:

{
  name
  relationship {
    name
  }
}

And will yield the subset of each object type queried:

{
  "name": "Mark Zuckerberg",
  "relationship": {
    "name": "Priscilla Chan"
  }
}

Result Coercion

Determining the result of coercing an object is the heart of the GraphQL executor, so this is covered in that section of the spec.

Input Coercion

Objects are never valid inputs.

3.1.2.1Object Field Arguments

Object fields are conceptually functions which yield values. Occasionally object fields can accept arguments to further specify the return value. Object field arguments are defined as a list of all possible argument names and their expected input types.

For example, a Person type with a picture field could accept an argument to determine what size of an image to return.

type Person {
  name: String
  picture(size: Int): Url
}

GraphQL queries can optionally specify arguments to their fields to provide these arguments.

This example query:

{
  name
  picture(size: 600)
}

May yield the result:

{
  "name": "Mark Zuckerberg",
  "picture": "http://some.cdn/picture_600.jpg"
}

The type of an object field argument can be any Input type.

3.1.2.2Object 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.

3.1.2.3Object type validation

Object types have the potential to be invalid if incorrectly defined. This set of rules must be adhered to by every Object type in a GraphQL schema.

  1. The fields of an Object type must have unique names within that Object type; no two fields may share the same name.
  2. 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 include an argument of the same name for every argument defined by the interface field.
        1. The object field argument must accept the same type (invariant) as the interface field argument.
      2. The object field must be of a type which is equal to the interface field.

3.1.3Interfaces

GraphQL Interfaces represent a list of named fields and their arguments. GraphQL object can then implement an interface, which guarantees that they will contain the specified fields.

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 may describe a required field and types such as Person or Business may then implement this interface.

interface NamedEntity {
  name: String
}

type Person : NamedEntity {
  name: String
  age: Int
}

type Business : NamedEntity {
  name: String
  employeeCount: Int
}

Fields which yield an interface are useful when one of many Object types are expected, but some fields should be guaranteed.

To continue the example, a Contact might refer to NamedEntity.

type Contact {
  entity: NamedEntity
  phoneNumber: String
  address: String
}

This allows us to write a query for a Contact that can select the common fields.

{
  entity {
    name
  }
  phoneNumber
}

When querying for 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:

{
  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:

{
  entity {
    name
    ... on Person {
      age
    }
  },
  phoneNumber
}

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

Interfaces are never valid inputs.

3.1.3.1Interface type validation

Interface types have the potential to be invalid if incorrectly defined.

  1. The fields of an Interface type must have unique names within that Interface type; no two fields may share the same name.

3.1.4Unions

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 typed fragments.

For example, we might have the following type system:

Union SearchResult = Photo | Person

type Person {
  name: String
  age: Int
}

type Photo {
  height: Int
  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:

{
  firstSearchResult {
    name
    height
  }
}

Instead, the query would be:

{
  firstSearchResult {
    ... on Person {
      name
    }
    ... on Photo {
      height
    }
  }
}

Result Coercion

The union type should have some way of determining which object a given result corresponds to. Once it has done so, the result coercion of the union is the same as the result coercion of the object.

Input Coercion

Unions are never valid inputs.

3.1.4.1Union type validation

Union types have the potential to be invalid if incorrectly defined.

  1. The member types of an Union type must all be Object base types; Scalar, Interface and Union types may not be member types of a Union. Similarly, wrapping types may not be member types of a Union.
  2. A Union type must define two or more member types.

3.1.5Enums

GraphQL Enums are a variant on the Scalar type, which represents one of a finite set of possible values.

GraphQL Enums are not references for a numeric value, but are unique values in their own right. They serialize as a string: the name of the represented value.

Result Coercion

GraphQL servers 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.

Query variable transport serializations which have a different representation for non‐string symbolic values (for example, 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.

3.1.6Input Objects

Fields can define arguments that the client passes up with the query, to configure their behavior. These inputs can be Strings or Enums, but they sometimes need to be more complex than this.

The Object type defined above is inappropriate for re‐use here, because Objects can contain fields that express circular references or 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.

An Input Object defines a set of input fields; the input fields are either scalars, enums, or other input objects. This allows arguments to accept arbitrarily complex structs.

Result Coercion

An input object is never a valid result.

Input Coercion

The input to an input object should be an unordered map, otherwise an error should be thrown. The result of the coercion is an unordered map, with an entry for each input field, whose key is the name of the input field. The value of an entry in the coerced map is the result of input coercing the value of the entry in the input with the same key; if the input does not have a corresponding entry, the value is the result of coercing null. The input coercion above should be performed according to the input coercion rules of the type declared by the input field.

3.1.7Lists

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].

Result Coercion

GraphQL servers 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 they 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.

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 as list, it should be coerced as though the input was a list of size one, where the value passed is the only item in the list. This is to allow inputs that accept a “var args” to declare their input type as a list; if only one argument is passed (a common case), the client can just pass that value rather than constructing the list.

3.1.8Non-Null

By default, all types in GraphQL are nullable; the null value is a valid response for all of the above types. To declare a type that disallows null, the GraphQL Non‐Null type can be used. This type declares an underlying type, and this type acts identically to that underlying 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!.

Result Coercion

In all of the above result coercion, null was considered a valid value. To coerce the result of a Non Null type, the result coercion of the underlying 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 an error should be raised.

Input Coercion

that `null` is not a value in GraphQL, so a query cannot look like:
{
  field(arg: null)
}

to indicate that the argument is null. Instead, an argument would be null only if it is omitted:

{
  field
}

Or if passed a variable of a nullable type that at runtime was not provided a value:

query withNullableVariable($var: String) {
  field(arg: $var)
}

Hence, if the value for a Non Null type is hard‐coded in the query, it is always coerced using the input coercion for the wrapped type.

When a Non Null input has its value set using a variable, the coerced value should be null if the provided value is null-like in the provided representation, or if the provided value is omitted. Otherwise, the coerced value is the result of running the wrapped type’s input coercion on the provided value.

3.2Directives

A GraphQL schema includes a list of the directives the execution engine supports.

GraphQL implementations should provide the @skip and @include directives.

3.2.1@skip

The @skip directive may be provided for fields or fragments, and allows for conditional exclusion during execution as described by the if argument.

In this example experimentalField will be queried only if the $someTest is provided a false value.

query myQuery($someTest: Boolean) {
  experimentalField @skip(if: $someTest)
}

3.2.2@include

The @include directive may be provided for fields or fragments, and allows for conditional inclusion during execution as described by the if argument.

In this example experimentalField will be queried only if the $someTest is provided a true value.

query myQuery($someTest: Boolean) {
  experimentalField @include(if: $someTest)
}

The @skip directive has precedence over the @include directive should both be provided in the same context.

3.3Starting types

A GraphQL schema includes types, indicating where query and mutation operations start. This provides the initial entry points into the type system. The query type must always be provided, and is an Object base type. The mutation type is optional; if it is null, that means the system does not support mutations. If it is provided, it must be an object base type.

The fields on the query type indicate what fields are available at the top level of a GraphQL query. For example, a basic GraphQL query like this one:

query getMe {
  me
}

Is valid when the type provided for the query starting type has a field named “me”. Similarly

mutation setName {
  setName(name: "Zuck") {
    newName
  }
}

Is valid when the type provided for the mutation starting type is not null, and has a field named “setName” with a string argument named “name”.

4Introspection

A GraphQL server supports introspection over its schema. This schema is queried using GraphQL itself, creating a powerful platform for tool‐building.

Take an example query for a trivial app. In this case there is a User type with three fields: id, user, and birthday.

For example, given a server with the following type definition:

type User {
  id: String
  name: String
  birthday: Date
}

The query

{
  __type(name: "User") {
    name
    fields {
      name
      type {
        name
      }
    }
  }
}

would return

{
  "__type": {
    "name" : "User",
    "fields": [
      {
        "name": "id",
        "type": { "name": "String" }
      },
      {
        "name": "name",
        "type": { "name": "String" }
      },
      {
        "name": "birthday",
        "type": { "name": "Date" }
      },
    ]
  }
}

4.1General Principles

4.1.1Naming conventions

Types and fields required by the GraphQL introspection system that are used in the same context as user‐defined type and fields are prefixed with two underscores. This in order to avoid naming collisions with user‐defined GraphQL types. Conversely, GraphQL type system authors must not define any types, fields, arguments, or any other type system artifact with two leading underscores.

4.1.2Documentation

All types in the introspection system provide a description field of type String to allow type designers to publish documentation in addition to capabilities. A GraphQL server may return the description field using Markdown syntax. Therefore it is recommended that any tool that displays description use a Markdown renderer.

4.1.3Deprecation

To support the management of backwards compatibility, GraphQL fields and enum values can indicate whether or not they are deprecated (isDeprecated: Boolean) and a description of why it is deprecated (deprecationReason: String).

Tools built using GraphQL introspection should respect deprecation by discouraging deprecated use through information hiding or developer‐facing warnings.

4.1.4Type Name Introspection

GraphQL supports type name introspection at any point within a query by the meta field __typename: String! when querying against any Object, Interface, or Union. It returns the name of the object type currently being queried.

This is most often used when querying against Interface or Union types to identify which actual type of the possible types has been returned.

This field is implicit and does not appear in the fields list in any defined type.

4.2Schema Introspection

The schema introspection system is accessible from the meta‐fields __schema and __type which are accessible from the type of the root of a query operation.

__schema : __Schema!
__type(name: String!) : __Type

These fields are implicit and do not appear in the fields list in the root type of the query operation.

The schema of the GraphQL schema introspection system:

type __Schema {
  types: [__Type!]!
  queryType: __Type!
  mutationType: __Type
  directives: [__Directive!]!
}

type __Type {
  kind: __TypeKind!
  name: String
  description: String

  # OBJECT and INTERFACE only
  fields(includeDeprecated: Boolean = false): [__Field!]

  # OBJECT only
  interfaces: [__Type!]

  # INTERFACE and UNION only
  possibleTypes: [__Type!]

  # ENUM only
  enumValues(includeDeprecated: Boolean = false): [__EnumValue!]

  # INPUT_OBJECT only
  inputFields: [__InputValue!]

  # NON_NULL and LIST only
  ofType: __Type
}

type __Field {
  name: String!
  description: String
  args: [__InputValue!]!
  type: __Type!
  isDeprecated: Boolean!
  deprecationReason: String
}

type __InputValue {
  name: String!
  description: String
  type: __Type!
  defaultValue: String
}

type __EnumValue {
  name: String!
  description: String
  isDeprecated: Boolean!
  deprecationReason: String
}

enum __TypeKind {
  SCALAR
  OBJECT
  INTERFACE
  UNION
  ENUM
  INPUT_OBJECT
  LIST
  NON_NULL
}

type __Directive {
  name: String!
  description: String
  args: [__InputValue!]!
  onOperation: Boolean!
  onFragment: Boolean!
  onField: Boolean!
}

4.2.1The “__Type” Type

__Type is at the core of the type introspection system. It represents scalars, interfaces, object types, unions, enums in the system.

__Type also represents type modifiers, which are used to modify a type that it refers to (ofType: __Type). This is how we represent lists, non‐nullable types, and the combinations thereof.

4.2.2Type Kinds

There are several different kinds of type. In each kind, different fields are actually valid. These kinds are listed in the __TypeKind enumeration.

4.2.2.1Scalar

Represents scalar types such as Int, String, and Boolean. Scalars cannot have fields.

A GraphQL type designer should describe the data format and scalar coercion rules in the description field of any scalar.

Fields

  • kind must return __TypeKind.SCALAR.
  • name must return a String.
  • description may return a String or null.
  • All other fields must return null.
4.2.2.2Object

Object types represent concrete instantiations of sets of fields. The introspection types (e.g. __Type, __Field, etc) are examples of objects.

Fields

  • kind must return __TypeKind.OBJECT.
  • name must return a String.
  • description may return a String or null.
  • fields: The set of fields query‐able on this type.
    • Accepts the argument includeDeprecated which defaults to false. If true, deprecated fields are also returned.
  • interfaces: The set of interfaces that an object implements.
  • All other fields must return null.
4.2.2.3Union

Unions are an abstract types where no common fields are declared. The possible types of a union are explicitly listed out in possibleTypes. Types can be made parts of unions without modification of that type.

Fields

  • kind must return __TypeKind.UNION.
  • name must return a String.
  • description may return a String or null.
  • possibleTypes returns the list of types that can be represented within this union. They must be object types.
  • All other fields must return null.
4.2.2.4Interface

Interfaces is an abstract type where there are common fields declared. Any type that implements an interface must define all the fields with names and types exactly matching. The implementations of this interface are explicitly listed out in possibleTypes.

Fields

  • kind must return __TypeKind.INTERFACE.
  • name must return a String.
  • description may return a String or null.
  • fields: The set of fields required by this interface.
    • Accepts the argument includeDeprecated which defaults to false. If true, deprecated fields are also returned.
  • possibleTypes returns the list of types that implement this interface. They must be object types.
  • All other fields must return null.
4.2.2.5Enum

Enums are special scalars that can only have a defined set of values.

Fields

  • kind must return __TypeKind.ENUM.
  • name must return a String.
  • description may return a String or null.
  • enumValues: The list of EnumValue. There must be at least one and they must have unique names.
    • Accepts the argument includeDeprecated which defaults to false. If true, deprecated enum values are also returned.
  • All other fields must return null.
4.2.2.6Input Object

Input objects are composite types used as inputs into queries defined as a list of named input values.

For example the input object Point could be defined as:

type Point {
  x: Int
  y: Int
}

Fields

  • kind must return __TypeKind.INPUT_OBJECT.
  • name must return a String.
  • description may return a String or null.
  • inputFields: a list of InputValue.
  • All other fields must return null.
4.2.2.7List

Lists represent sequences of values in GraphQL. A List type is a type modifier: it wraps another type instance in the ofType field, which defines the type of each item in the list.

Fields

  • kind must return __TypeKind.LIST.
  • ofType: Any type.
  • All other fields must return null.
4.2.2.8Non-null

GraphQL types are nullable. The value null is a valid response for field type.

A Non‐null type is a type modifier: it wraps another type instance in the ofType field. Non‐null types do not allow null as a response, and indicate required inputs for arguments and input object fields.

  • kind must return __TypeKind.NON_NULL.
  • ofType: Any type except Non‐null.
  • All other fields must return null.
4.2.2.9Combining List and Non-Null

List and Non‐Null can compose, representing more complex types.

If the modified type of a List is Non‐Null, then that List may not contain any null items.

If the modified type of a Non‐Null is List, then null is not accepted, however an empty list is accepted.

If the modified type of a List is a List, then each item in the first List is another List of the second List’s type.

A Non‐Null type cannot modify another Non‐Null type.

5Validation

GraphQL does not just verify if a request is syntactically correct.

Prior to execution, it can also verify that a request is valid within the context of a given GraphQL schema. Validation is primarily targeted at development‐time tooling. Any client‐side tooling should return errors and not allow the formulation of queries known to violate the type system at a given point in time.

Total request validation on the server‐side during execution is optional. As schemas and systems change over time existing clients may end up emitting queries that are no longer valid given the current type system. Servers (as described in the Execution section of this spec) attempt to satisfy as much as the request as possible and continue to execute in the presence of type system errors rather than cease execution completely.

For this section of this schema, we will assume the following type system in order to demonstrate examples:

enum DogCommand { SIT, DOWN, HEEL }

type Dog : Pet {
  name: String!
  nickname: String
  barkVolume: Int
  doesKnowCommand(dogCommand: DogCommand!) : Boolean!
  isHousetrained(atOtherHomes: Boolean): Boolean!
}

interface Sentient {
  name: String!
}

interface Pet {
  name: String!
}

type Alien : Sentient {
  name: String!
  homePlanet: String
}

type Human : Sentient {
  name: String!
}

type Cat : Pet {
  name: String!
  nickname: String
  meowVolume: Int
}

union CatOrDog = Cat | Dog
union DogOrHuman = Dog | Human
union HumanOrAlien = Human | Alien

5.1Fields

5.1.1Field Selections on Objects, Interfaces, and Unions Types

Formal Specification

  • For each selection in the document.
  • Let fieldName be the target field of selection
  • fieldName must be defined on type in scope

Explanatory Text

The target field of a field selection must defined on the scoped type of the selection set. There are no limitations on alias names.

For example the following fragment would not pass validation:

fragment fieldNotDefined on Dog {
  meowVolume
}

fragment aliasedLyingFieldTargetNotDefined on Dog {
  barkVolume: kawVolume
}

For interfaces, direct field selection can only be done on fields. Fields of concrete implementors is not relevant to the validity of the given interface‐typed selection set.

For example, the following is valid:

fragment interfaceFieldSelection on Pet {
  name
}

and the following is invalid:

fragment definedOnImplementorsButNotInterface on Pet {
  nickname
}

Because fields are not declared on unions, direct field selection on union‐typed selection set. This is true even if concrete implementors of the union define the fieldName.

For example the following is invalid

fragment directFieldSelectionOnUnion on CatOrDog {
  directField
}

fragment definedOnImplementorsQueriedOnUnion on CatOrDog {
  name
}

5.1.2Field Selection Merging

Formal Specification

  • Let set be any selection set defined in the GraphQL document
  • Let setForKey be the set of selections with a given response key in set
  • All members of setForKey must:
    • Have identical target fields
    • Have identical sets of arguments.
    • Have identical sets of directives.

Explanatory Text

Selection names are de‐duplicated and merged for validation, but the target field, arguments, and directives must all be identical.

For human‐curated GraphQL, this rules seem a bit counterintuitive since it appears to be clear developer error. However in the presence of nested fragments or machine‐generated GraphQL, requiring unique selections is a burdensome limitation on tool authors.

The following selections correctly merge:

fragment mergeIdenticalFields on Dog {
  name
  name
}

fragment mergeIdenticalAliasesAndFields on Dog {
  otherName: name
  otherName: name
}

The following is not able to merge:

fragment conflictingBecauseAlias on Dog {
  name: nickname
  name
}

Identical arguments are also merged if they have identical arguments. Both values and variables can be correctly merged.

For example the following correctly merge:

fragment mergeIdenticalFieldsWithIdenticalArgs on Dog {
  doesKnowCommand(dogCommand: SIT)
  doesKnowCommand(dogCommand: SIT)
}

fragment mergeIdenticalFieldsWithIdenticalValues on Dog {
  doesKnowCommand(dogCommand: $dogCommand)
  doesKnowCommand(dogCommand: $dogCommand)
}

The following do not correctly merge:

fragment conflictingArgsOnValues on Dog {
  doesKnowCommand(dogCommand: SIT)
  doesKnowCommand(dogCommand: HEEL)
}

fragment conflictingArgsValueAndVar on Dog {
  doesKnowCommand(dogCommand: SIT)
  doesKnowCommand(dogCommand: $dogCommand)
}

fragment conflictingArgsWithVars on Dog {
  doesKnowCommand(dogCommand: $varOne)
  doesKnowCommand(dogCommand: $varTwo)
}

The same logic applies to directives. The set of directives on each selection with the same response key in a given scope must be identical.

The following is valid:

fragment mergeSameFieldsWithSameDirectives on Dog {
  name @include(if: true)
  name @include(if: true)
}

and the following is invalid:

fragment conflictingDirectiveArgs on Dog {
  name @include(if: true)
  name @include(if: false)
}

5.1.3Leaf Field Selections

Formal Specification

  • For each selection in the document
  • Let selectionType be the result type of selection
  • If selectionType is a scalar:
    • The subselection set of that selection must be empty
  • If selectionType is an interface, union, or object
    • The subselection set of that selection must NOT BE empty

Explanatory Text

Field selections on scalars are never allowed: scalars are the leaf nodes of any GraphQL query.

The following is valid.

fragment scalarSelection: Dog {
  barkVolume
}

The following is invalid.

fragment scalarSelectionsNotAllowedOnBoolean : Dog {
  barkVolume {
    sinceWhen
  }
}

Conversely the leaf field selections of GraphQL queries must be scalars. Leaf selections on objects, interfaces, and unions without subfields are disallowed.

Let’s assume the following query root type of the schema:

type QueryRoot {
  human: Human
  pet: Pet
  catOrDog: CatOrDog
}

The following examples are invalid

query directQueryOnObjectWithoutSubFields {
  human
}

query directQueryOnInterfaceWithoutSubFields {
  pet
}

query directQueryOnUnionWithoutSubFields {
  catOrDog
}

5.2Arguments

Arguments are provided to both fields and directives. The following validation rules apply in both cases.

5.2.1Argument Names

Formal Specification

  • For each argument in the document
  • Let argumentName be the Name of argument.
  • Let argumentDefinition be the argument definition provided by the parent field or definition named argumentName.
  • argumentDefinition must exist.

Explanatory Text

Every argument provided to a field or directive must be defined in the set of possible arguments of that field or directive.

For example the following are valid:

fragment argOnRequiredArg on Dog {
  doesKnowCommand(dogCommand: SIT)
}

fragment argOnOptional on Dog {
  isHousetrained(atOtherHomes: true) @include(if: true)
}

the following is invalid since command is not defined on DogCommand.

fragment invalidArgName on Dog {
  doesKnowCommand(command: CLEAN_UP_HOUSE)
}

and this is also invalid as unless is not defined on @include.

fragment invalidArgName on Dog {
  isHousetrained(atOtherHomes: true) @include(unless: false)
}

In order to explore more complicated argument examples, let’s add the following to our type system:

type Arguments {
  multipleReqs(x: Int!, y: Int!)
  booleanArgField(booleanArg: Boolean)
  floatArgField(floatArg: Float)
  intArgField(intArg: Int)
  nonNullBooleanArgField(nonNullBooleanArg: Boolean!)
}

Order does not matter in arguments. Therefore both the following example are valid.

fragment multipleArgs on Arguments {
  multipleReqs(x: 1, y: 2)
}

fragment multipleArgsReverseOrder on Arguments {
  multipleReqs(y: 1, x: 2)
}

5.2.2Argument Values Type Correctness

5.2.2.1Compatible Values

Formal Specification

  • For each argument in the document
  • Let value be the Value of argument
  • If value is not a Variable
    • Let argumentName be the Name of argument.
    • Let argumentDefinition be the argument definition provided by the parent field or definition named argumentName.
    • Let type be the type expected by argumentDefinition.
    • The type of literalArgument must be coercible to type.

Explanatory Text

Literal values must be compatible with the type defined by the argument they are being provided to, as per the coercion rules defined in the Type System chapter.

For example, an Int can be coerced into a Float.

fragment goodBooleanArg on Arguments {
  booleanArgField(booleanArg: true)
}

fragment coercedIntIntoFloatArg on Arguments {
  floatArgField(floatArg: 1)
}

An incoercible conversion, is string to int. Therefore, the following example is invalid.

fragment stringIntoInt on Arguments {
  intArgField(intArg: "3")
}
5.2.2.2Required Arguments
  • For each Field or Directive in the document.
  • Let arguments be the arguments provided by the Field or Directive.
  • Let argumentDefinitions be the set of argument definitions of that Field or Directive.
  • For each definition in argumentDefinitions
    • Let type be the expected type of definition
    • If type is Non‐Null
      • Let argumentName be the name of definition
      • Let argument be the argument in arguments named argumentName
      • argument must exist.

Explanatory Text

Arguments can be required. Arguments are required if the type of the argument is non‐null. If it is not non‐null, the argument is optional.

For example the following are valid:

fragment goodBooleanArg on Arguments {
  booleanArgField(booleanArg: true)
}

fragment goodNonNullArg on Arguments {
  nonNullBooleanArgField(nonNullBooleanArg: true)
}

The argument can be omitted from a field with a nullable argument.

Therefore the following query is valid:

fragment goodBooleanArgDefault on Arguments {
  booleanArgField
}

but this is not valid on a non‐null argument.

fragment missingRequiredArg on Arguments {
  notNullBooleanArgField
}

5.3Fragments

5.3.1Fragment Declarations

5.3.1.1Fragment Spread Type Existence

Formal Specification

  • For each named spread namedSpread in the document
  • Let fragment be the target of namedSpread
  • The target type of fragment must be defined in the schema

Explanatory Text

Fragments must be specified on types that exist in the schema. This applies for both named and inline fragments. If they are not defined in the schema, the query does not validate.

For example the following fragments are valid:

fragment correctType on Dog {
  name
}

fragment inlineFragment on Dog {
  ... on Dog {
    name
  }
}

and the following do not validate:

fragment notOnExistingType on NotInSchema {
  name
}

fragment inlineNotExistingType on Dog {
  ... on NotInSchema {
    name
  }
}
5.3.1.2Fragments On Composite Types

Formal Specification

  • For each fragment defined in the document.
  • The target type of fragment must have kind UNION, INTERFACE, or OBJECT.

Explanatory Text

Fragments can only be declared on unions, interfaces, and objects. They are invalid on scalars. They can only be applied on non‐leaf fields. This rule applies to both inline and named fragments.

The following fragment declarations are valid:

fragment fragOnObject on Dog {
  name
}

fragment fragOnInterface on Pet {
  name
}

fragment fragOnUnion on CatOrDog {
  ... on Dog {
    name
  }
}

and the following are invalid:

fragment fragOnScalar on Int {
  something
}

fragment inlineFragOnScalar on Dog {
  ... on Boolean {
    somethingElse
  }
}
5.3.1.3Fragments Must Be Used

Formal Specification

  • For each fragment defined in the document.
  • fragment must be the target of at least one spread in the document

Explanatory Text

Defined fragments must be used within a query document.

For example the following is an invalid query document:

fragment nameFragment on Dog { # unused
  name
}

{
  dog {
    name
  }
}

5.3.2Fragment Spreads

Field selection is also determined by spreading fragments into one another. The selection set of the target fragment is unioned with the selection set at the level at which the target fragment is referenced.

5.3.2.1Fragment spread target defined

Formal Specification

  • For every namedSpread in the document.
  • Let fragment be the target of namedSpread
  • fragment must be defined in the document

Explanatory Text

Named fragment spreads must refer to fragments defined within the document. If the target of a spread is not defined, this is an error:

{
  dog {
    ...undefinedFragment
  }
}
5.3.2.2Fragment spreads must not form cycles

Formal Specification

  • For each fragmentDefinition in the document
  • Let visited be the empty set.
  • DetectCycles(fragmentDefinition, visited)

DetectCycles(fragmentDefinition, visited) :

  • Let spreads be all fragment spread descendants of fragmentDefinition
  • For each spread in spreads
    • visited must not contain spread
    • Let nextVisited be the set including spread and members of visited
    • Let nextFragmentDefinition be the target of spread
    • DetectCycles(nextFragmentDefinition, nextVisited)

Explanatory Text

The graph of fragment spreads must not form any cycles including spreading itself. Otherwise an operation could infinitely spread or infinitely execute on cycles in the underlying data.

This invalidates fragments that would result in an infinite spread:

{
  dog {
    ...nameFragment
  }
}

fragment nameFragment on Dog {
  name
  ...barkVolumeFragment
}

fragment barkVolumeFragment on Dog {
  barkVolume
  ...nameFragment
}

If the above fragments were inlined, this would result in the infinitely large:

{
  dog {
    name
    barkVolume
    name
    barkVolume
    name
    barkVolume
    name
    # forever...
  }
}

This also invalidates fragments that would result in an infinite recursion when executed against cyclic data:

{
  dog {
    ...dogFragment
  }
}

fragment dogFragment on Dog {
  name
  owner {
    ...ownerFragment
  }
}

fragment ownerFragment on Dog {
  name
  pets {
    ...dogFragment
  }
}
5.3.2.3Fragment spread is possible

Formal Specification

  • For each spread (named or inline) in defined in the document.
  • Let fragment be the target of spread
  • Let fragmentType be the type condition of fragment
  • Let parentType be the type of the selection set containing spread
  • Let applicableTypes be the intersection of GetPossibleTypes(fragmentType) and GetPossibleTypes(parentType)
  • applicableTypes must not be empty.
[GetPossibleTypes](#GetPossibleTypes())(type)
  1. If type is an object type, return a set containing type
  2. If type is an interface type, return the set of types implementing type
  3. If type is a union type, return the set of possible types of type

Explanatory Text

Fragments are declared on a type and will only apply when the runtime object type matches the type condition. They also are spread within the context of a parent type. A fragment spread is only valid if its type condition could ever apply within the parent type.

and the following valid fragments:

5.3.2.3.1Object Spreads In Object Scope

In the scope of a object type, the only valid object type fragment spread is one that applies to the same type that is in scope.

For example

fragment dogFragment on Dog {
  ... on Dog {
    barkVolume
  }
}

and the following is invalid

fragment catInDogFragmentInvalid on Dog {
  ... on Cat {
    meowVolume
  }
}
5.3.2.3.2Abstract Spreads in Object Scope

In scope of an object type, unions or interface spreads can be used if the object type implements the interface or is a member of the union.

For example

fragment petNameFragment on Pet {
  name
}

fragment interfaceWithinObjectFragment on Dog {
  ...petNameFragment
}

is valid because Dog implements Pet.

Likewise

fragment catOrDogNameFragment on CatOrDog {
  ... on Cat {
    meowVolume
  }
}

fragment unionWithObjectFragment on Dog {
  ...CatOrDogFragment
}

is valid because Dog is a member of the CatOrDog union. It is worth noting that if one inspected the contents of the CatOrDogNameFragment you could note that the no valid results would ever be returned. However we do not specify this as invalid because we only consider the fragment declaration, not its body.

5.3.2.3.3Object Spreads In Abstract Scope

Union or interface spreads can be used within the context of an object type fragment, but only if the object type is one of the possible types of the that interface or union.

For example, the following fragments are valid:

fragment petFragment on Pet {
  name
  ... on Dog {
    barkVolume
  }
}

fragment catOrDogFragment on CatOrDog {
  ... on Cat {
    meowVolume
  }
}

petFragment is valid because Dog implements the interface Pet. catOrDogFragment is valid because Cat is a member of the CatOrDog union.

By contrast the following fragments are invalid:

fragment sentientFragment on Sentient {
  ... on Dog {
    barkVolume
  }
}

fragment humanOrAlienFragment on HumanOrAlien {
  ... on Cat {
    meowVolume
  }
}

Dog does not implement the interface Sentient and therefore sentientFragment can never return meaningful results. Therefore the fragment is invalid. Likewise Cat is not a member of the union HumanOrAlien, and it can also never return meaningful results, making it invalid.

5.3.2.3.4Abstract Spreads in Abstract Scope

Union or interfaces fragments can be used within each other. As long as there exists at least one object type that exists in the intersection of the possible types of the scope and the spread, the spread is considered valid.

So for example

fragment unionWithInterface on Pet {
  ...dogOrHumanFragment
}

fragment dogOrHumanFragment on DogOrHuman {
  ... on Dog {
    barkVolume
  }
}

is consider valid because Dog implements interface Pet and is a member of DogOrHuman.

However

fragment nonIntersectingInterfaces on Pet {
  ...sentientFragment
}

fragment sentientFragment on Sentient {
  name
}

is not valid because there exists no type that implements both Pet and Sentient.

5.4Directives

5.4.1Directives Are Defined

Formal Specification

  • For every directive in a document.
  • Let directiveName be the name of directive.
  • Let directiveDefinition be the directive named directiveName.
  • directiveDefinition must exist.

Explanatory Text

GraphQL servers define what directives they support. For each usage of a directive, the directive must be available on that server.

5.5Operations

5.5.1Variables

5.5.1.1Variable Default Values Are Correctly Typed

Formal Specification

  • For every operation in a document
  • For every variable on each operation
    • Let variableType be the type of variable
    • If variableType is non‐null it cannot have a default value
    • If variable has a default value it must be of the same types or able to be coerced to variableType

Explanatory Text

Variable defined by operations are allowed to define default values if the type of that variable not non‐null.

For example the following query will pass validation.

query houseTrainedQuery($atOtherHomes: Boolean = true) {
  dog {
    isHousetrained(atOtherHomes: $atOtherHomes)
  }
}

However if the variable is defined as non‐null, default values are unreachable. Therefore queries such as the following fail validation

query houseTrainedQuery($atOtherHomes: Boolean! = true) {
  dog {
    isHousetrained(atOtherHomes: $atOtherHomes)
  }
}

Default values must be compatible with the types of variables. Types much match or they must be coercible to the type.

Non‐matching types fail, such as in the following example:

query houseTrainedQuery($atOtherHomes: Boolean = "true") {
  dog {
    isHousetrained(atOtherHomes: $atOtherHomes)
  }
}

However if a type is coercible the query will pass validation.

For example:

query intToFloatQuery($floatVar: Float = 1) {
  arguments {
    floatArgField(floatArg: $floatVar)
  }
}
5.5.1.2Variables Are Input Types

Formal Specification

  • For every operation in a document
  • For every variable on each operation
    • Let variableType be the type of variable
    • While variableType is LIST or NON_NULL
      • Let variableType be the referenced type of variableType
    • variableType must of kind SCALAR, ENUM or INPUT_OBJECT

Explanatory Text

Variables can only be scalars, enums, input objects, or lists and non‐null variants of those types. These are known as input types. Object, unions, and interfaces cannot be used as inputs.

The following queries are valid:

query takesBoolean($atOtherHomes: Boolean) {
  # ...
}

query takesComplexInput($complexInput: ComplexInput) {
  # ...
}

query TakesListOfBooleanBang($booleans: [Boolean!]) {
  # ...
}

The following queries are invalid:

query takesCat($cat: Cat) {
  # ...
}

query takesDogBang($dog: Dog!) {
  # ...
}

query takesListOfPet($pets: [Pet]) {
  # ...
}

query takesCatOrDog($catOrDog: CatOrDog) {
  # ...
}
5.5.1.3All Variable Uses Defined

Formal Specification

  • For each operation in a document
    • For each variableUsage in scope, variable must be operation’s variable list.
    • Let fragments be every fragment reference by that operation transitively
    • For each fragment in fragments
      • For each variableUsage in scope of fragment, variable must be operation‘s variable list.

Explanatory Text

Variables are scoped on a per‐operation basis. That means that any variable used within the context of a operation must be defined at the top level of that operation

For example:

query variableIsDefined($atOtherHomes: Boolean) {
  dog {
    isHousetrained(atOtherHomes: $booleanArg)
  }
}

is valid. $atOtherHomes is defined by the operation.

By contrast the following query is invalid:

query variableIsNotDefined {
  dog {
    isHousetrained(atOtherHomes: $atOtherHomes)
  }
}

$atOtherHomes is not defined by the operation.

Fragments complicate this rule. Any fragment transitively included by an operation has access to the variables defined by that operation. Fragments can appear within multiple operations and therefore variable usages must correspond to variable definitions in all of those operations.

For example the following is valid:

query variableIsDefinedUsedInSingleFragment($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes}
}

since isHousetrainedFragment is used within the context of the operation variableIsDefinedUsedInSingleFragment and the variable is defined by that operation.

On the contrary is a fragment is included within an operation that does not define a referenced variable, this is a validation error.

query variableIsNotDefinedUsedInSingleFragment {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes}
}

This applies transitively as well, so the following also fails:

query variableIsNotDefinedUsedInNestedFragment {
  dog {
    ...outerHousetrainedFragment
  }
}

fragment outerHousetrainedFragment on Dog {
  ...isHousetrainedFragment
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes}
}

Variables must be defined in all operations in which a fragment is used.

query housetrainedQueryOne($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

query housetrainedQueryTwo($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes}
}

However the following does not validate:

query housetrainedQueryOne($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

query housetrainedQueryTwoNotDefined {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes)
}

This is because housetrainedQueryTwoNotDefined does not define a variable $atOtherHomes but that variable is used by isHousetrainedFragment which is included in that operation.

5.5.1.4All Variables Used

Formal Specification

  • For every operation in the document.
  • Let variables be the variables defined by that operation
  • Each variable in variables must be used at least once in either the operation scope itself or any fragment transitively referenced by that operation.

Explanatory Text

All variables defined by an operation must be used in that operation or a fragment transitively included by that operation. Unused variables cause a validation error.

For example the following is invalid:

query variableUnused($atOtherHomes: Boolean) {
  dog {
    isHousetrained
  }
}

because $atOtherHomes in not referenced.

These rules apply to transitive fragment spreads as well:

query variableUsedInFragment($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes)
}

The above is valid since $atOtherHomes is used in isHousetrainedFragment which is included by variableUsedInFragment.

If that fragment did not have a reference to $atOtherHomes it would be not valid:

query variableNotUsedWithinFragment($atOtherHomes: Boolean) {
  ...isHousetrainedWithoutVariableFragment
}

fragment isHousetrainedWithoutVariableFragment on Dog {
  isHousetrained
}

All operations in a document must use all of their variables.

As a result, the following document does not validate.

query queryWithUsedVar($atOtherHomes: Boolean) {
  dog {
    ...isHousetrainedFragment
  }
}

query queryWithExtraVar($atOtherHomes: Boolean, $extra: Int) {
  dog {
    ...isHousetrainedFragment
  }
}

fragment isHousetrainedFragment on Dog {
  isHousetrained(atOtherHomes: $atOtherHomes)
}

This document is not valid because queryWithExtraVar defines an extraneous variable.

5.5.1.5All Variable Usages are Allowed

Formal Specification

  • For each operation in document
  • Let variableUsages be all usages transitively included in the operation
  • For each variableUsage in variableUsages
    • Let variableType be the type of variable definition in the operation
    • Let argumentType be the type of the argument the variable is passed to.
    • Let hasDefault be true if the variable definition defines a default.
    • AreTypesCompatible(argumentType, variableType, hasDefault) must be true
  • AreTypesCompatible(argumentType, variableType, hasDefault):
    • If hasDefault is true, treat the variableType as non‐null.
    • If inner type of argumentType and variableType be different, return false
    • If argumentType and variableType have different list dimensions, return false
    • If any list level of variableType is not non‐null, and the corresponding level in argument is non‐null, the types are not compatible.

Explanatory Text

Variable usages must be compatible with the arguments they are passed to.

Validation failures occur when variables are used in the context of types that are complete mismatches, or if a nullable type in a variable is passed to a not‐null argument type.

Types must match:

query intCannotGoIntoBoolean($intArg: Int) {
  arguments {
    booleanArgField(booleanArg: $intArg)
  }
}

$intArg typed as Int cannot be used as a argument to booleanArg, typed as Boolean.

List cardinality must also be the same. For example, lists cannot be passed into singular values.

query booleanListCannotGoIntoBoolean($booleanListArg: [Boolean]) {
  arguments {
    booleanArgField(booleanArg: $booleanListArg)
  }
}

Nullability must also be respected. In general a nullable variable cannot be passed to a non‐null argument.

query booleanArgQuery($booleanArg: Boolean) {
  arguments {
    nonNullBooleanArgField(nonNullBooleanArg: $booleanArg)
  }
}

A notable exception is when default arguments are provided. They are, in effect, treated as non‐nulls.

query booleanArgQueryWithDefault($booleanArg: Boolean = true) {
  arguments {
    nonNullBooleanArgField(nonNullBooleanArg: $booleanArg)
  }
}

For list types, the same rules around nullability apply to both outer types and inner types. A nullable list cannot be passed to a non‐null list, and a lists of nullable values cannot be passed to a list of non‐null values.

query nonNullListToList($nonNullBooleanList: ![Boolean]) {
  arguments {
    booleanListArgField(booleanListArg: $nonNullBooleanList)
  }
}

However a nullable list could not be passed to a non‐null list.

query listToNonNullList($booleanList: [Boolean]) {
  arguments {
    nonNullBooleanListField(nonNullBooleanListArg: $booleanList)
  }
}

This would fail validation because a [T] cannot be passed to a [T]!.

Similarly a [T] cannot be passed to a [T!].

6Execution

This section describes how GraphQL generates a response from a request.

6.1Evaluating requests

To evaluate a request, the executor must have a parsed Document (as defined in the “Query Language” part of this spec) and a selected operation name to run if the document defines multiple operations.

The executor should find the Operation in the Document with the given operation name. If no such operation exists, the executor should throw an error. If the operation is found, then the result of evaluating the request should be the result of evaluating the operation according to the “Evaluating operations” section.

6.2Evaluating operations

The type system, as described in the “Type System” part of the spec, must provide a “Query Root” and a “Mutation Root” object.

If the operation is a mutation, the result of the operation is the result of evaluating the mutation’s top level selection set on the “Mutation Root” object. This selection set should be evaluated serially.

If the operation is a query, the result of the operation is the result of evaluating the query’s top level selection set on the “Query Root” object.

6.3Evaluating selection sets

To evaluate a selection set, the executor needs to know the object on which it is evaluating the set and whether it is being evaluated serially.

If the selection set is being evaluated on the null object, then the result of evaluating the selection set is null.

Otherwise, the selection set is turned into a grouped field set; each entry in the grouped field set is a list of fields that share a responseKey.

The selection set is converted to a grouped field set by calling CollectFields, initializing visitedFragments to an empty list.

[CollectFields](#CollectFields())(objectType, selectionSet, visitedFragments)
  1. Initialize groupedFields to an empty list of lists.
  2. For each selection in selectionSet;
    1. If selection provides the directive @skip, let skipDirective be that directive.
      1. If skipDirective‘s if argument is true, continue with the next selection in selectionSet.
    2. If selection provides the directive @include, let includeDirective be that directive.
      1. If includeDirective‘s if argument is false, continue with the next selection in selectionSet.
    3. If selection is a Field:
      1. Let responseKey be the response key of selection.
      2. Let groupForResponseKey be the list in groupedFields for responseKey; if no such list exists, create it as an empty list.
      3. Append selection to the groupForResponseKey.
    4. If selection is a FragmentSpread:
      1. Let fragmentSpreadName be the name of selection.
      2. If fragmentSpreadName is in visitedFragments, continue with the next selection in selectionSet.
      3. Add fragmentSpreadName to visitedFragments.
      4. Let fragment be the Fragment in the current Document whose name is fragmentSpreadName.
      5. If no such fragment exists, continue with the next selection in selectionSet.
      6. Let fragmentType be the type condition on fragment.
      7. If doesFragmentTypeApply(objectType, fragmentType) is false, continue with the next selection in selectionSet.
      8. Let fragmentSelectionSet be the top‐level selection set of fragment.
      9. Let fragmentGroupedFields be the result of calling CollectFields(objectType, fragmentSelectionSet).
      10. For each fragmentGroup in fragmentGroupedFields: 1. Let responseKey be the response key shared by all fields in fragmentGroup 2. Let groupForResponseKey be the list in groupedFields for responseKey; if no such list exists, create it as an empty list. 3. Append all items in fragmentGroup to groupForResponseKey.
    5. If selection is an inline fragment:
      1. Let fragmentType be the type condition on selection.
      2. If doesFragmentTypeApply(objectType, fragmentType) is false, continue with the next selection in selectionSet.
      3. Let fragmentSelectionSet be the top‐level selection set of selection.
      4. Let fragmentGroupedFields be the result of calling CollectFields(objectType, fragmentSelectionSet).
      5. For each fragmentGroup in fragmentGroupedFields:
        1. Let responseKey be the response key shared by all fields in fragmentGroup
        2. Let groupForResponseKey be the list in groupedFields for responseKey; if no such list exists, create it as an empty list.
        3. Append all items in fragmentGroup to groupForResponseKey.
  3. Return groupedFields.
[doesFragmentTypeApply](#doesFragmentTypeApply())(objectType, fragmentType)
  1. If fragmentType is an Object Type:
    1. if objectType and fragmentType are the same type, return true, otherwise return false.
  2. If fragmentType is an Interface Type:
    1. if objectType is an implementation of fragmentType, return true otherwise return false.
  3. If fragmentType is a Union:
    1. if objectType is a possible type of fragmentType, return true otherwise return false.

The result of evaluating the selection set is the result of evaluating the corresponding grouped field set. The corresponding grouped field set should be evaluated serially if the selection set is being evaluated serially, otherwise it should be evaluated normally.

6.4Evaluating a grouped field set

The result of evaluating a grouped field set will be an unordered map. There will be an entry in this map for every item in the grouped field set.

6.4.1Field entries

Each item in the grouped field set can potentially create an entry in the result map. That entry in the result map is the result is the result of calling GetFieldEntry on the corresponding item in the grouped field set. GetFieldEntry can return null, which indicates that there should be no entry in the result map for this item. Note that this is distinct from returning an entry with a string key and a null value, which indicates that an entry in the result should be added for that key, and its value should be null.

GetFieldEntry assumes the existence of two functions that are not defined in this section of the spec. It is expected that the type system provides these methods:

  • ResolveFieldOnObject, which takes an object type, a field, and an object, and returns the result of resolving that field on the object.
  • GetFieldTypeFromObjectType, which takes an object type and a field, and returns that field’s type on the object type, or null if the field is not valid on the object type.
[GetFieldEntry](#GetFieldEntry())(objectType, object, fields)
  1. Let firstField be the first entry in the ordered list fields. Note that fields is never empty, as the entry in the grouped field set would not exist if there were no fields.
  2. Let responseKey be the response key of firstField.
  3. Let fieldType be the result of calling GetFieldTypeFromObjectType(objectType, firstField).
  4. If fieldType is null, return null, indicating that no entry exists in the result map.
  5. Let resolvedObject be ResolveFieldOnObject(objectType, object, fieldEntry).
  6. If resolvedObject is null, return tuple(responseKey, null), indicating that an entry exists in the result map whose value is null.
  7. Let subSelectionSet be the result of calling MergeSelectionSets(fields).
  8. Let responseValue be the result of calling CompleteValue(fieldType, resolvedObject, subSelectionSet).
  9. Return tuple(responseKey, responseValue).
[GetFieldTypeFromObjectType](#GetFieldTypeFromObjectType())(objectType, firstField)
  1. Call the method provided by the type system for determining the field type on a given object type.
[ResolveFieldOnObject](#ResolveFieldOnObject())(objectType, object, firstField)
  1. Call the method provided by the type system for determining the resolution of a field on a given object.
[MergeSelectionSets](#MergeSelectionSets())(fields)
  1. Let selectionSet be an empty list.
  2. For each field in fields:
    1. Let fieldSelectionSet be the selection set of field.
    2. If fieldSelectionSet is null or empty, continue to the next field.
    3. Append all selections in fieldSelectionSet to selectionSet.
  3. Return selectionSet.
[CompleteValue](#CompleteValue())(fieldType, result, subSelectionSet)
  1. If the fieldType is a Non‐Null type:
    1. Let innerType be the inner type of fieldType.
    2. Let completedResult be the result of calling CompleteValue(innerType, result).
    3. If completedResult is null, throw a field error.
    4. Return completedResult.
  2. If result is null or a value similar to null such as undefined or NaN, return null.
  3. If fieldType is a List type:
    1. If result is not a collection of values, throw a field error.
    2. Let innerType be the inner type of fieldType.
    3. Return a list where each item is the result of calling CompleteValue(innerType, resultItem), where resultItem is each item in result.
  4. If fieldType is a Scalar or Enum type:
    1. Return the result of “coercing” result, ensuring it is a legal value of fieldType, otherwise null.
  5. If fieldType is an Object, Interface, or Union type:
    1. Return the result of evaluating subSelectionSet on fieldType normally.

6.4.2Normal evaluation

When evaluating a grouped field set without a serial execution order requirement, the executor can determine the entries in the result map in whatever order it chooses. Because the resolution of fields other than top‐level mutation fields is always side effect–free and idempotent, the execution order must not affect the result, and hence the server has the freedom to evaluate the field entries in whatever order it deems optimal.

For example, given the following grouped field set to be evaluated normally:

{
  birthday {
    month
  }
  address {
    street
  }
}

A valid GraphQL executor can resolve the four fields in whatever order it chose.

6.4.3Serial execution

Observe that based on the above sections, the only time an executor will run in serial execution order is on the top level selection set of a mutation operation and on its corresponding grouped field set.

When evaluating a grouped field set serially, the executor must consider each entry from the grouped field set in the order provided in the grouped field set. It must determine the corresponding entry in the result map for each item to completion before it continues on to the next item in the grouped field set:

For example, given the following selection set to be evaluated serially:

{
  changeBirthday(birthday: $newBirthday) {
    month
  }
  changeAddress(address: $newAddress) {
    street
  }
}

The executor must, in serial:

  • Run getFieldEntry for changeBirthday, which during CompleteValue will evaluate the { month } sub‐selection set normally.
  • Run getFieldEntry for changeAddress, which during CompleteValue will evaluate the { street } sub‐selection set normally.

As an illustrative example, let’s assume we have a mutation field changeTheNumber that returns an object containing one field, theNumber. If we execute the following selection set serially:

{
  first: changeTheNumber(newNumber: 1) {
    theNumber
  }
  second: changeTheNumber(newNumber: 3) {
    theNumber
  }
  third: changeTheNumber(newNumber: 2) {
    theNumber
  }
}

The executor will evaluate the following serially:

  • Resolve the changeTheNumber(newNumber: 1) field
  • Evaluate the { theNumber } sub‐selection set of first normally
  • Resolve the changeTheNumber(newNumber: 3) field
  • Evaluate the { theNumber } sub‐selection set of second normally
  • Resolve the changeTheNumber(newNumber: 2) field
  • Evaluate the { theNumber } sub‐selection set of third normally

A correct executor must generate the following result for that selection set:

{
  "first": {
    "theNumber": 1
  },
  "second": {
    "theNumber": 3
  },
  "third": {
    "theNumber": 2
  }
}

6.4.4Error handling

If an error occurs when resolving a field, it should be treated as though the field returned null, and an error must be added to the “errors” list in the response.

6.4.5Nullability

If the result of resolving a field is null (either because the function to resolve the field returned null or because an error occurred), and that field is marked as being non‐null in the type system, then the result of evaluating the entire field set that contains this field is now null.

If the field was null because of an error, then the error has already been logged, and the “errors” list in the response must not be affected.

If the field resolution function returned null, and the field was non‐null, then no error has been logged, so an appropriate error must be added to the “errors” list.

7Response

When a GraphQL server receives a request, it must return a well‐formed response. The server’s response describes the result of executing the requested operation if successful, and describes any errors encountered during the request.

A response may contain both a partial response as well as encountered errors in the case that an error occurred on a field which was replaced with null.

7.1Serialization Format

GraphQL does not require a specific serialization format. However, clients should use a serialization format that supports the major primitives in the GraphQL response. In particular, the serialization format must support representations of the following four primitives:

  • Map
  • List
  • String
  • Null

A serialization format may support the following primitives, however, strings may be used as a substitute for those primitives.

  • Boolean
  • Int
  • Float
  • Enum Value

7.1.1JSON Serialization

JSON is the preferred serialization format for GraphQL, though as noted above, GraphQL does not require a specific serialization format. For consistency and ease of notation, examples of the response are given in JSON throughout the spec. In particular, in our JSON examples, we will represent primitives using the following JSON concepts:

GraphQL ValueJSON Value
MapObject
ListArray
Nullnull
StringString
Booleantrue or false
IntNumber
FloatNumber
Enum ValueString

7.2Response Format

A response to a GraphQL operation must be a map.

If the operation included execution, the response map must contain an entry with key data. The value of this entry is described in the “Data” section. If the operation failed before execution, due to a syntax error, missing information, or validation error, this entry must not be present.

If the operation encountered any errors, the response map must contain an entry with key errors. The value of this entry is described in the “Errors” section. If the operation completed without encountering any errors, this entry must not be present.

The response map may also contain an entry with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to extend the protocol however they see fit, and hence there are no additional restrictions on its contents.

To ensure future changes to the protocol do not break existing servers and clients, the top level response map must not contain any entries other than the three described above.

7.2.1Data

The data entry in the response will be the result of the execution of the requested operation. If the operation was a query, this output will be an object of the schema’s query root type; if the operation was a mutation, this output will be an object of the schema’s mutation root type.

If an error was encountered before execution begins, the data entry should not be present in the result.

If an error was encountered during the execution that prevented a valid response, the data entry in the response should be null.

7.2.2Errors

The errors entry in the response is a non‐empty list of errors, where each error is a map.

If no errors were encountered during the requested operation, the errors entry should not be present in the result.

Every error must contain an entry with the key message with a string description of the error intended for the developer as a guide to understand and correct the error.

If an error can be associated to a particular point in the requested GraphQL document, it should contain an entry with the key locations with a list of locations, where each location is a map with the keys line and column, both positive numbers starting from 1 which describe the beginning of an associated syntax element.

GraphQL servers may provide additional entries to error as they choose to produce more helpful or machine‐readable errors, however future versions of the spec may describe additional entries to errors.

If the data entry in the response is null or not present, the errors entry in the response must not be empty. It must contain at least one error. The errors it contains should indicate why no data was able to be returned.

If the data entry in the response is not null, the errors entry in the response may contain any errors that occurred during execution. If errors occurred during execution, it should contain those errors.

AAppendix: Notation Conventions

This specification document contains a number of notation conventions used to describe technical concepts such as language grammar and semantics as well as runtime algorithms.

This appendix seeks to explain these notations in greater detail to avoid ambiguity.

A.1Context-Free Grammar

A context‐free grammar consists of a number of productions. Each production has an abstract symbol called a “non‐terminal” as its left‐hand side, and zero or more possible sequences of non‐terminal symbols and or terminal characters as its right‐hand side.

Starting from a single goal non‐terminal symbol, a context‐free grammar describes a language: the set of possible sequences of characters that can be described by repeatedly replacing any non‐terminal in the goal sequence with one of the sequences it is defined by, until all non‐terminal symbols have been replaced by terminal characters.

Terminals are represented in this document in a monospace font in two forms: a specific unicode character or sequence of unicode characters (ex. = or terminal), and a pattern of unicode characters defined by a regular expression (ex /[0-9]+/).

Non‐terminal production rules are represented in this document using the following notation for a non‐terminal with a single definition:

[NonTerminalWithSingleDefinition](#NonTerminalWithSingleDefinition)
NonTerminalterminal

While using the following notation for a production with a list of definitions:

[NonTerminalWithManyDefinitions](#NonTerminalWithManyDefinitions)
OtherNonTerminalterminal
terminal

A definition may refer to itself, which describes repetitive sequences, for example:

[ListOfLetterA](#ListOfLetterA)
a
[ListOfLetterA](#ListOfLetterA)a

A.2Lexical and Syntactical Grammar

The GraphQL language is defined in a syntactic grammar where terminal symbols are tokens. Tokens are defined in a lexical grammar which matches patterns of source characters. The result of parsing a sequence of source unicode characters produces a GraphQL AST.

A Lexical grammar production describes non‐terminal “tokens” by patterns of terminal unicode characters. No “whitespace” or other ignored characters may appear between any terminal unicode characters in the lexical grammar production. A lexical grammar production is distinguished by a two colon :: definition.

[Word](#Word)
/[A-Za-z]+/

A Syntactical grammar production describes non‐terminal “rules” by patterns of terminal Tokens. Whitespace and other ignored characters may appear before or after any terminal Token. A syntactical grammar production is distinguished by a one colon : definition.

[Sentence](#Sentence)
NounVerb

A.3Grammar Notation

This specification uses some additional notation to describe common patterns, such as optional or repeated patterns, or parameterized alterations of the definition of a non‐terminal. This section explains these short‐hand notations and their expanded definitions in the context‐free grammar.

Constraints

A grammar production may specify that certain expansions are not permitted by using the phrase “but not” and then indicating the expansions to be excluded.

For example, the production:

[SafeName](#SafeName)
[Name](#Name)SevenCarlinWords

means that the nonterminal SafeName may be replaced by any sequence of characters that could replace Name provided that the same sequence of characters could not replace SevenCarlinWords.

A grammar may also list a number of restrictions after “but not” seperated by “or”.

For example:

[NonBooleanName](#NonBooleanName)
[Name](#Name)truefalse

Optionality and Lists

A subscript suffix “Symbolopt” is shorthand for two possible sequences, one including that symbol and one excluding it.

As an example:

[Sentence](#Sentence)
NounVerbAdverbopt

is shorthand for

[Sentence](#Sentence)
NounVerb
NounVerbAdverb

A subscript suffix “Symbollist” is shorthand for a list of one or more of that symbol.

As an example:

[Book](#Book)
CoverPagelistCover

is shorthand for

[Book](#Book)
Cover[Page_list](#Page_list)Cover
[Page_list](#Page_list)
Page
[Page_list](#Page_list)Page

Parameterized Grammar Productions

A symbol definition subscript suffix parameter in braces “SymbolParam” is shorthand for two symbol definitions, one appended with that parameter name, the other without. The same subscript suffix on a symbol is shorthand for that variant of the definition. If the parameter starts with “?”, that form of the symbol is used if in a symbol definition with the same parameter. Some possible sequences can be included or excluded conditionally when respectively prefixed with “[+Param]” and “[~Param]”.

As an example:

[Example](#Example)Param
A
BParam
CParam
ParamD
ParamE

is shorthand for

[Example](#Example)
A
B_param
C
E
[Example_param](#Example_param)
A
B_param
C_param
D

A.4Grammar Semantics

This specification describes the semantic value of many grammar productions in the form of a list of algorithmic steps.

For example, this describes how a parser should interpret a unicode escape sequence which appears in a string literal:

[EscapedUnicode](#EscapedUnicode)
u/[0-9A-Fa-f]{4}/
  1. Let codePoint be the number represented by the four‐digit hexidecimal sequence.
  2. The string value is the unicode character represented by codePoint.

A.5Algorithms

This specification describes some algorithms used by the static and runtime semantics, they’re defined in the form of a function‐like syntax along with a list of algorithmic steps to take.

For example, this describes if a fragment should be spread into place given a runtime objectType and the fragment’s fragmentType:

[doesFragmentTypeApply](#doesFragmentTypeApply())(objectType, fragmentType)
  1. If fragmentType is an Object Type:
    1. if objectType and fragmentType are the same type, return true, otherwise return false.
  2. If fragmentType is an Interface Type:
    1. if objectType is an implementation of fragmentType, return true otherwise return false.
  3. If fragmentType is a Union:
    1. if objectType is a possible type of fragmentType, return true otherwise return false.

BAppendix: Grammar Summary

[SourceCharacter](#SourceCharacter)
Any Unicode code point

B.1Ignored Tokens

[Ignored](#Ignored)
[WhiteSpace](#WhiteSpace)
[LineTerminator](#LineTerminator)
[Comment](#Comment)
[Comma](#Comma)
[WhiteSpace](#WhiteSpace)
Horizontal Tab (U+0009)
Vertical Tab (U+000B)
Form Feed (U+000C)
Space (U+0020)
No-break Space (U+00A0)
[LineTerminator](#LineTerminator)
New Line (U+000A)
Carriage Return (U+000D)
Line Separator (U+2028)
Paragraph Separator (U+2029)
[Comment](#Comment)
#[CommentChar](#CommentChar)listopt
[CommentChar](#CommentChar)
[SourceCharacter](#SourceCharacter)[LineTerminator](#LineTerminator)
[Comma](#Comma)
,

B.2Lexical Tokens

[Token](#Token)
[Punctuator](#Punctuator)
[Name](#Name)
[IntValue](#IntValue)
[FloatValue](#FloatValue)
[StringValue](#StringValue)
[Punctuator](#Punctuator)

| ! | $ | ( | ) | | : | = | @ | [ | ] | { | | | } |

[Name](#Name)
/[_A-Za-z][_0-9A-Za-z]*/
[IntValue](#IntValue)
[IntegerPart](#IntegerPart)
[IntegerPart](#IntegerPart)
[NegativeSign](#NegativeSign)opt0
[NegativeSign](#NegativeSign)opt[NonZeroDigit](#NonZeroDigit)[Digit](#Digit)listopt
[NegativeSign](#NegativeSign)
-
[Digit](#Digit)

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

[NonZeroDigit](#NonZeroDigit)
[Digit](#Digit)0
[FloatValue](#FloatValue)
[IntegerPart](#IntegerPart)[FractionalPart](#FractionalPart)
[IntegerPart](#IntegerPart)[ExponentPart](#ExponentPart)
[IntegerPart](#IntegerPart)[FractionalPart](#FractionalPart)[ExponentPart](#ExponentPart)
[FractionalPart](#FractionalPart)
.[Digit](#Digit)list
[ExponentPart](#ExponentPart)
[ExponentIndicator](#ExponentIndicator)[Sign](#Sign)opt[Digit](#Digit)list
[ExponentIndicator](#ExponentIndicator)

| e | E |

[Sign](#Sign)

| + | - |

[StringValue](#StringValue)
""
"[StringCharacter](#StringCharacter)list"
[StringCharacter](#StringCharacter)
[SourceCharacter](#SourceCharacter)"\[LineTerminator](#LineTerminator)
\[EscapedUnicode](#EscapedUnicode)
\[EscapedCharacter](#EscapedCharacter)
[EscapedUnicode](#EscapedUnicode)
u/[0-9A-Fa-f]{4}/
[EscapedCharacter](#EscapedCharacter)

| | </span> | / | b | f | n | r | t |

B.3Query Document

[Document](#Document)
[Definition](#Definition)list
[Definition](#Definition)
[OperationDefinition](#OperationDefinition)
[FragmentDefinition](#FragmentDefinition)
[OperationDefinition](#OperationDefinition)
[SelectionSet](#SelectionSet)
[OperationType](#OperationType)[Name](#Name)[VariableDefinitions](#VariableDefinitions)opt[Directives](#Directives)opt[SelectionSet](#SelectionSet)
[OperationType](#OperationType)

| query | mutation |

[SelectionSet](#SelectionSet)
{[Selection](#Selection)list}
[Selection](#Selection)
[Field](#Field)
[FragmentSpread](#FragmentSpread)
[InlineFragment](#InlineFragment)
[Field](#Field)
[Alias](#Alias)opt[Name](#Name)[Arguments](#Arguments)opt[Directives](#Directives)opt[SelectionSet](#SelectionSet)opt
[Alias](#Alias)
[Name](#Name):
[Arguments](#Arguments)
([Argument](#Argument)list)
[Argument](#Argument)
[Name](#Name):[Value](#Value)
[FragmentSpread](#FragmentSpread)
...[FragmentName](#FragmentName)[Directives](#Directives)opt
[InlineFragment](#InlineFragment)
...on[TypeCondition](#TypeCondition)[Directives](#Directives)opt[SelectionSet](#SelectionSet)
[FragmentDefinition](#FragmentDefinition)
fragment[FragmentName](#FragmentName)on[TypeCondition](#TypeCondition)[Directives](#Directives)opt[SelectionSet](#SelectionSet)
[FragmentName](#FragmentName)
[Name](#Name)on
[TypeCondition](#TypeCondition)
[NamedType](#NamedType)
[Value](#Value)Const
Const[Variable](#Variable)
[IntValue](#IntValue)
[FloatValue](#FloatValue)
[StringValue](#StringValue)
[BooleanValue](#BooleanValue)
[EnumValue](#EnumValue)
[ListValue](#ListValue)Const
[ObjectValue](#ObjectValue)Const
[BooleanValue](#BooleanValue)

| true | false |

[EnumValue](#EnumValue)
[Name](#Name)truefalsenull
[ListValue](#ListValue)Const
[]
[[Value](#Value)Constlist]
[ObjectValue](#ObjectValue)Const
{}
{[ObjectField](#ObjectField)Constlist}
[ObjectField](#ObjectField)Const
[Name](#Name):[Value](#Value)Const
[VariableDefinitions](#VariableDefinitions)
([VariableDefinition](#VariableDefinition)list)
[VariableDefinition](#VariableDefinition)
[Variable](#Variable):[Type](#Type)[DefaultValue](#DefaultValue)opt
[Variable](#Variable)
$[Name](#Name)
[DefaultValue](#DefaultValue)
=[Value](#Value)Const
[Type](#Type)
[NamedType](#NamedType)
[ListType](#ListType)
[NonNullType](#NonNullType)
[NamedType](#NamedType)
[Name](#Name)
[ListType](#ListType)
[[Type](#Type)]
[NonNullType](#NonNullType)
[NamedType](#NamedType)!
[ListType](#ListType)!
[Directives](#Directives)
[Directive](#Directive)list
[Directive](#Directive)
@[Name](#Name)[Arguments](#Arguments)opt
Written in [Spec Markdown](http://leebyron.com/spec-md/).

Related Posts

译自2011- A Year in Review at HIMSS12 by Keith Boone

译自2011- A Year in Review at HIMSS12 by Keith Boone

译2011: A Year in Review at HIMSS12 by Keith Boone Keith Boone是我一直在关注 在follow的老头子,虽然好像还是蛮年轻 ,一直找不到很好的地方 很好的网站 大多数网站在外面实验室糟糕的代理模式下是压根发表不了新帖的。不幸的科学网就这样躺在中枪了。 周一 2月20日 2012 2011:HIMISS12 过去一年的回顾 通常H

read more
CDA快速入门

CDA快速入门

在大概了解了CDA文档实例的模样,手头上也有了各式各样自己喜好的XML编辑器,那么我们可能就希望实践一把。该怎么做呢? 如果你希望先了解CDA前前后后的一些东西,那么你需要看看下面的PPT 1.参考各个机构所带来的对CDA介绍的PPT 台湾范士展老师整理的相关资料 [mayo的资料](http://dl.dbank.co

read more
Health eDecision 项目收尾Clinical Quality Framework项目启动

Health eDecision 项目收尾Clinical Quality Framework项目启动

[原文链接](http://www.healthit.gov/buzz-blog/electronic-health-and-medical-records/interoperability-electronic-health-and-medical-records/standards-interoperability-framework-milestones-health-edecision

read more
Data Versus Information- The EMR Readability Problem  by  Bruce Friedman

Data Versus Information- The EMR Readability Problem by Bruce Friedman

两篇来自 Bruce Friedman的博文 http://labsoftnews.typepad.com/lab_soft_news/2012/08/data-vs-information-the-emr-readability-problem.htmlhttp://labsoftnews.typepad.com/lab_soft_news/2012/08/data-vs-informati

read more
EHR架构与设计相关材料

EHR架构与设计相关材料

EHR Architecture and Design by Jerome Carter on March 25, 2013 **Updated August 26, 2014 **<span style="color

read more
对FHIR的一些浅显认识

对FHIR的一些浅显认识

FHIR标准 大多数在HIT这个行业浸淫略久的人都听到过HL7的字眼,HIT 行业的标准不外乎有2个目的,交互共享数据(HL7 V2消息,V3消息,CDA,X12,共享文档规范诸如此类),表达医疗行业的知识(各类术语字典,数据集数据元标准,Arden syntax,CDSC,GELLO诸如此类),而FHIR应该归属于第一类,与它的前辈不同的是,它抛弃了既往顺着发展了10多年,乃至于20年的那块

read more
FHIR——介绍

FHIR——介绍

http://www.hl7.org/implement/standards/fhir/introduction.htm 介绍Introduction Fast Healthcare Interoperability Resources 定义了一个医疗卫生资源的集合。这些资源所表达的是一个个模块化的医学概念,通过交换它们以达到在医疗保健及相关流程中快速高效地解决问题。这些资源涵盖了医疗卫生的基

read more
FHIR概览

FHIR概览

自去年Grahame Grieve引出v3 has failed的讨论之后,RFH的出现似乎给HL7带来了一些生机。从RFH到FHIR 自是经过一番努力。越来越多的人对此表示出极大的兴趣,菜鸟我也不例外。故拟在后面的一些篇章中对目前所有的一些的资料进行一些简单的介绍和试译。 来到Grahame Grieve自己维护的博客主站(链接)上,在右侧links处即可看到一些相关信息,点击Fast Hea

read more
译自Good Exchange Specifications- Microsoft vs Apple  by Grahame Grieve

译自Good Exchange Specifications- Microsoft vs Apple by Grahame Grieve

译自Good Exchange Specifications: Microsoft vs Apple by Grahame Grieve 构建一个标准之初你必须要做的选择之一是如何进行领域分析。这是一个你如何使用story board故事版的问题。这里有苹果的做法,也有微软的做法。 苹果的做法 苹果的方法很简单:你以文档形式记录下你的story board,然后为你所接受的story

read more
HL7 need a fresh look

HL7 need a fresh look

此间,由Grahame Grieve发表的一篇题为HL7 Fresh Look Task Force的博文引起了人们的热烈的讨论,RIMBAA的邮件列表里讨论了很久,随后Grahame Grieve 又发表一些后续的相关博文,Keith Boone也有一些,今日又看到Wes Rishel的一篇题为Lessons From the Putative Failure of HL7 V3的博文,当然

read more
how to understand  Health Concern

how to understand Health Concern

Health Concern的概念是我一直捉摸不透的, 为什么要有这样的一个概念 最近在FHIR 的mailing list上有一些探讨 收集以供自己了理解The conundrum of the observation-concern-

read more
译自Implementing IHE SVS Over the Trifolia Consolidated CDA by  Keith Boone

译自Implementing IHE SVS Over the Trifolia Consolidated CDA by Keith Boone

Friday, March 9, 2012 BY Keith Boone Implementing IHE SVS Over the Trifolia Consolidated CDA Database 这个32行的程序是为了让JSP页面能够根据Trifolia Workbench database 构建一个 IHE SVS Value Set 的实现。它完全没有处理任何错误,如果变量匹配

read more
译Introducing NHIN Direct NHIN Direct的介绍 by Keith Boone

译Introducing NHIN Direct NHIN Direct的介绍 by Keith Boone

原文链接 之所以关注这篇文章的作者是因为之前一直在看Keith Boone的Blog,从他的首页上看到了几个人的Blog的外链,Keith这么胸猛,他推荐的人自然不会逊色。他们也将成为我在茫茫Healthcare Standards的知识海洋中学习的几

read more
译自Liberating Consolidated CDA Templates from the Trifolia  Keith Boone

译自Liberating Consolidated CDA Templates from the Trifolia Keith Boone

Tuesday, March 6, 2012 By Keith Boone Liberating Consolidated CDA Templates from the Trifolia Workbench Data CDA Consolidation project的目标之一是从模板的模型驱动数据中自动化的构建验证和开发工具。我曾期望与MDHT项目有更加紧密的合作,我希望最终能够实现。几个星期

read more
译《A Perfect Implementation Guide》by Keith Boone

译《A Perfect Implementation Guide》by Keith Boone

分类: What the New Meaningful Use Standards for Electronic Health Records Mean 原文链接 http://www.dietsinreview.com/diet_column/07/new-standards-for-electronic-health-records/ 就在周二,联邦政府发布了题为“Electronic

read more
译自The XSLT document() function  by  Keith Boone

译自The XSLT document() function by Keith Boone

Thursday, January 26, 2012 BY Keith Boone The XSLT document() function 有人在Structured Document 工作组邮件列表中问了一个如

read more
译自Value Sets and QueryHealth  by  Keith Boone

译自Value Sets and QueryHealth by Keith Boone

Tuesday, November 1, 2011 By Keith Boone Value Sets and QueryHealth Query Health的一大难题就是一个特殊的measure就可能引用大量的编码值。在HL7中

read more
译《A Perfect Implementation Guide》by Keith Boone

译《A Perfect Implementation Guide》by Keith Boone

Tuesday, February 1, 2011 A Perfect Implementation Guide 英文原文链接 在上周HL7/IHE/ONC Consolidation Project的电话会议上,其中两个人同意新增

read more
a-review-of-all-most-common-api-editor-API-Specification-Automated-Testing-Documentation-Generation

a-review-of-all-most-common-api-editor-API-Specification-Automated-Testing-Documentation-Generation

需求1、DSL:要能够使用DSL来描述定义API 2、DSL编辑工具:要有易用的编辑工具来编写API定义 3、API的校验:最终的AP定义要能够可执行,可以用来确认API的动作 最好是cURL或者浏览器的服务交互来分析请求响应 4、API文档:从API定义中可以自动生成文档 5、解析器:支持多种语言,能从IDL中生成客户端代码,java、js、php、ruby、pytho

read more
<微服务架构在Netflix的应用>系列博文-4 微服务架构在Netflix的应用:团队和流程设计相关的经验教训

<微服务架构在Netflix的应用>系列博文-4 微服务架构在Netflix的应用:团队和流程设计相关的经验教训

第四篇-微服务架构在Netflix的应用:团队和流程设计相关的经验教训 <微服务架构在Netflix的应用>系列博文-共四篇 英文版: [第一部分: The Four-Tier Engagement Platform]((http://blogs.forrester.com/ted_schadler/13-11-20-mobile_needs_a_four_tier_eng

read more
Bottled Water-PostgreSQL与 Kafka的实时数据整合

Bottled Water-PostgreSQL与 Kafka的实时数据整合

Bottled Water: PostgreSQL与 Kafka 的实时数据整合 英文版: [Bottled Water: Real-time integration of PostgreSQL and Kafka](http://blog.confluent.io/2015/04/23/bottled-water-real-time-integration-of-post

read more
CDA文档编辑器

CDA文档编辑器

CDA文档均为XML文件,故我们采用一些市面上常用的XML编辑软件。列举如下: 1.Oxygen XML Editor 它是一款基于Java的XML编辑器,支持XML, XSL, TXT, XSD, DTD文档,能自行校验XML, XSL, XSD代码,提示脚本错误。Oxygen能自动完成结束标签,代码高亮现实,支持Unicode。 Oxygen XML Editor是一款简洁并且功能一流

read more
CDA文档实例

CDA文档实例

关于CDA R2的学习,很多人可能想直接看看这样那样的一些例子,下面是我所搜集的一些 1.来自Rene Spronk整理的压缩包,里面有丰富的内容 包含了很多国家不同项目的一些实例 下载链接一(原作者提供的) [下载链接二(方便一些无法下载一)](http://dl.dbank.

read more
 第一篇-CDS应该集成到那些业务流程当中

第一篇-CDS应该集成到那些业务流程当中

一.美国卫生部的网站上对这个问题进行了一个归纳和总结,见Workflow Taxonomy,大致上翻译了一个版本参考附件[Reference Taxonomy of Clinical Workflows.xlsx](http://

read more
译自Defining a Summary Care Record for MeaningfulUse Stage2 by Keith Boone

译自Defining a Summary Care Record for MeaningfulUse Stage2 by Keith Boone

Wednesday, March 14, 2012 By Keith Boone Defining a Summary Care Record for MeaningfulUse Stage2 作者在文中提到“他在昨天的post中 描述了Meaningful Use Stage 2 rules中所存在的对于Summary Care Record的描述的混乱之处。今天他将进一步来简化它们。

read more
一些关于encounter就诊的概念

一些关于encounter就诊的概念

文中的文字和图片均来自http://gforge.hl7.org/gf/project/patient-admin/docman/?subdir=311

read more
一些读医学信息学论文时遇到专业词汇的解决办法

一些读医学信息学论文时遇到专业词汇的解决办法

读论文是每个学生必修课之一 不管是主动抑或被动 其中一些专业词汇 对于我等非医学专业的it逼来说 着实困难。 解决办法 1网上查呗 最直接的就是google 关键词 如 episode of care 请具备基本的鉴别能力 推荐网站 http://www.reference.md/ 应该是美国FDA的网站吧 还是比较全 http://www.wisegeek.com/health.htm

read more
关系型数据库向KAFKA迁移 FROM RELATIONAL INTO KAFKA

关系型数据库向KAFKA迁移 FROM RELATIONAL INTO KAFKA

关系型数据库向KAFKA迁移 FROM RELATIONAL INTO KAFKA 英文版: FROM RELATIONAL INTO KAFKA 中文版:[关系型数据库向KAFKA迁移](http://wanghaisheng.github.io/2015

read more
Github pages 个人主页和项目主页的不同设置

Github pages 个人主页和项目主页的不同设置

Github pages 个人主页和项目主页的不同设置 如果你想利用github pages来搭建属于自己的博客 亦或是为某个小项目做一个宣传页面 这里有点小坑 大家需要提防一下。 1.如果你想做一个个人主页的话,比如我在github建了这样一个repo,除了需要有

read more
API 文档编写工具

API 文档编写工具

API 文档编写工具 https://github.com/mashery/iodocs

read more
理解JSON Schema

理解JSON Schema

1、http://spacetelescope.github.io/understanding-json-schema/index.html 2、https://github.com/e-plus-healthcare-alliance/Open-mHealth-generic-and-clinical-schemas 理解JSON Schema

read more
 从零开始学临床决策支持 CDSS-第一篇 扒扒美国卫生部网站上的资料

从零开始学临床决策支持 CDSS-第一篇 扒扒美国卫生部网站上的资料

美国卫生部网站上有关CDS的内容 What is Clinical Decision Support (CDS)? Clinical decision support (CDS) provides clinicians, staff, patients or other individuals with knowledge and person-specific information,

read more
从零开始学临床决策支持CDSS-第二篇 如何将临床决策支持与医疗信息系统的业务流程整合起来

从零开始学临床决策支持CDSS-第二篇 如何将临床决策支持与医疗信息系统的业务流程整合起来

title: 从零开始学临床决策支持CDSS-第二篇 如何将临床决策支持与医疗信息系统的业务流程整合起来 date: 2015-2-11 19:53:12 updated : permalink: tags:医疗信息标准 CDSS HIT 临床决策支持 categories: 医疗信息标准 临床决策支持如何将临床决策支持与医疗信息系统的业务流程整合起

read more
<微服务架构在Netflix的应用>系列博文-3 微服务架构在Netflix的应用:架构设计的经验教训

<微服务架构在Netflix的应用>系列博文-3 微服务架构在Netflix的应用:架构设计的经验教训

第三篇-微服务架构在Netflix的应用:架构设计的经验教训 <微服务架构在Netflix的应用>系列博文-共四篇 英文版: [第一部分: The Four-Tier Engagement Platform]((http://blogs.forrester.com/ted_schadler/13-11-20-mobile_needs_a_four_tier_engagemen

read more
<微服务架构在Netflix的应用>系列博文-1 移动应用所需要的四层架构

<微服务架构在Netflix的应用>系列博文-1 移动应用所需要的四层架构

第一篇-移动应用所需要的四层架构 <微服务架构在Netflix的应用>系列博文-共四篇 英文版: 第一部分: The Four-Tier Engagement Platform 中文

read more
医疗开源实现

医疗开源实现

Cross Enterprise Document Sharing 跨机构文档共享 IheOS http://sourceforge.net/projects/iheos/ IheOS源自NIST本来做原始的XDS规范测试的(现在不做这个了)的参考实现的工作。Bill Majurski是XDS的创始人,并且不止是XDS规范的核心人员之一,也是这个开源项目的核心之一,也是很多由IHE开发

read more
openCDS系列 I——内部数据结构

openCDS系列 I——内部数据结构

译自Notes on OpenCDS Internal Data Structure 目的 openCDS的内部数据结构大致上是基于HL7 2011年9月份投票版中VMR(虚拟医疗记录)的逻辑模型。该逻辑模型中严格定义了所有的数据元素,数据元素的定义都有对应的内部数据结构。 内部数据结构更多地与schema保持一致,schema是对逻辑模型的说明性补充材料。schema 提供了2种方式来定义

read more
openCDS系列 II——使用openCDS中的概念

openCDS系列 II——使用openCDS中的概念

使用openCDS中的概念Using OpenCDS Concepts内容 1 什么是openCDS中的概念1.1概念类型1.2openCDS中的概念1.3概念映射规范1.4概念映射实例<div

read more
共同构建互联网医疗大共荣圈-FHIR标准的汉化和产品的开发

共同构建互联网医疗大共荣圈-FHIR标准的汉化和产品的开发

互联网医疗在过去的一年里如火如荼,希望大家能够一起来汉化和开发FHIR相关的产品 FHIR – Fast Health Interoperable Resources (hl7.org/fhir) – 是由HL7创建的新一代标准框架.FHIR 整合了 HL7 V2,V3 和 CDA 的优点,同时利用了最新的Web标准,紧紧围绕着 implementability 可实现性. FHIR 解决方

read more
病人记录的健康信息PGHD指南

病人记录的健康信息PGHD指南

病人记录的健康信息PGHD指南 为的是定义和提出一个将患者记录的健康信息整合到临床实践中的流程。有人在GG的博客上问了这样的一个问题,随着各种穿戴式设备和消费者端的网站越来越多,如何使用Fhir来记录和表达患者记录的健康信息,这些信息又如何与传统的医疗信息系统整合,在患者的诊疗

read more
病人记录的健康信息PGHD概念

病人记录的健康信息PGHD概念

病人记录的健康信息PGHD patient-generated health-information (PGHI) or patient-generated health data (PGHD). 这样一些在医院、医疗机构之外由患者或护理人员创建、收集、记录的与某个健康问题相关的观察、检验结果、 抑或是对已有EHR中某项数据的确认或变更等信息。 这样的信息在患者诊疗或健康管理过程中究

read more
piqi学习

piqi学习

#piqi学习 *目标一:·piqi是什么 *目标二:piqi与FHIR整合的可能性评估 *目标三:piqi用在文档内容校验上的可能性 *目标四:基于piqi的消息引擎的设计 ##piqi FAQ *1. piq和JSON的区别在哪里Piq语言适合与人机交互,JSON则只是一种标准的、轻便的、高效的结构化数据的表达方式。 The Piq language is optim

read more
Docker玩转Rhadoop

Docker玩转Rhadoop

Docker 玩转 RHadoop 网络上已经有了太多的 RHadoop 的安装使用的教程,鉴于其中的配置配置繁复,对软件版本的要求又极其苛刻,故笔者想用时下热门的 docker 来尝尝鲜,以下是心路历程,供看客参考,希望能给大家一些帮助。 1、软硬件环境 操作系统:OXS 10.10.1 docker安装版本:boot2docker(推荐大家使用https://gi

read more
Yelp公司总结的微服务架构的实践经验

Yelp公司总结的微服务架构的实践经验

Yelp公司总结的微服务架构的实践经验 英文版: Service Principles 中文版: Yelp公司总结的微服务架构的实践经验/ Service

read more
显示特定的标签值

显示特定的标签值

From looking at your XSLT and expected results, it looks like that for each a element in your XML, you want to output infomation on the following c elements present, if any occur before the next a e

read more
关于科研-启动翻译计划

关于科研-启动翻译计划

关于科研-启动翻译计划 一个人的战斗 两个人的战斗 三年的时间眨眼间逝去 无outcome可言 可我也self-study了不少。 决定了的事就去做 每天进步一点点 书籍 Principles of Health Interoperability HL7 and SNOMED Benson, Tim 1st Edition., 2010, XXIV, 263 p. 68 illus

read more
<微服务架构在Netflix的应用>系列博文-2 是时候转移到四层架构上来了

<微服务架构在Netflix的应用>系列博文-2 是时候转移到四层架构上来了

第二篇-是时候转移到四层架构上来了 <微服务架构在Netflix的应用>系列博文-共四篇 英文版: 第一部分: The Four-Tier Engagement Platform 中

read more
TWITTER REST API研究

TWITTER REST API研究

原文标题:REST APIs 原文作者:Twitter Inc 原文来源:Twitter Inc 译者: edwin_uestc REST APIs 这样就能够以编程的方式读写Twitter数据。发一条推或者读取某个人

read more
ubuntu下sqlplus上下光标键乱码解决方法

ubuntu下sqlplus上下光标键乱码解决方法

ubuntu下sqlplus上下光标键乱码解决方法 我的系统是ubuntu10.10,oracle版本为10gXE 遇到如题所述的问题时,可以这样解决该问题: 1 、安装插件: sudo apt-get install rlwrap 2、在当前用户下设置一个命令别名: alias sqlplus='rlwrap sqlplus' 3、重新键入

read more
读< 与Roy Fielding谈论版本化、超媒体以及REST >

读< 与Roy Fielding谈论版本化、超媒体以及REST >

第一篇,读< 与Roy Fielding谈论版本化、超媒体以及REST > 全系列Web APIs: From Start to Finish 第一篇,读< 与Roy Fielding谈论版本化、超媒体以及REST > [中文版](http://www.in

read more
读< 从业务角度看API >

读< 从业务角度看API >

第二篇,读< 从业务角度看API > 英文 中文 作者:Matt McLarty 观点1:API是当今信息技术趋势的核心,比如说移动终端、云计算、物联网、大数据、社交网络。涉足各行各业,如能源、汽车、电商等 观点2:虽然和API在整个技术领域

read more
医疗质量改进-表达知识的概念模型

医疗质量改进-表达知识的概念模型

HL7 Domain Analysis Model: Health Quality Improvement, Release 1 September 2014 US Realm Informative Specification文档 9/16/14 Introduction简介 目前在美国,电子化的医疗质量测度eCQM和临床决策支持CDS是采用不同的数据模型来表达的

read more
招妓小伙伴打小怪兽了

招妓小伙伴打小怪兽了

本人正在致力于FHIR(FHIR is a new emerging and appealing healthcare exchange standards, with the all difficulty embedded,through the off the shelf Web standards,you can flood health information anywhere on

read more