Last active
March 13, 2022 19:42
-
-
Save odigity/a80f73854106706785b1646948f971f0 to your computer and use it in GitHub Desktop.
GraphQL Cheat Sheet (not yet updated for 2021)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
┌────────────────────────────┐ | |
• Overview | |
• Types | |
• Server Examples | |
• Client Examples | |
• Responses | |
• Errors & Non-Nullability | |
• Subscriptions | |
└────────────────────────────┘ | |
┌──────────┐ | |
──┤ Overview ├───────────────────────────────────────────────────────────────── | |
└──────────┘ | |
GraphQL consists of a type system, query language and execution semantics, static validation, and type introspection. | |
Server Document (aka Schema) | |
• list of object type defs (inc roots -> Query/Mutation/Subscription) | |
• field defs | |
• arguments defs -aka- input value defs | |
Client Document (aka Query or Request) | |
• list of operation defs | |
• variable defs | |
• selection set -aka- fields | |
• arguments (literals|variables) | |
• desired operation name | |
• values for variables -> values for arguments | |
Fragments are the primary unit of query composition in GraphQL. | |
── Schema & Roots ── | |
# optional / implicit | |
schema { | |
query: Query | |
mutation: Mutation | |
subscription: Subscription | |
} | |
┌───────┐ | |
──┤ Types ├──────────────────────────────────────────────────────────────────── | |
└───────┘ | |
── Input Types & Output Types ── | |
Input Types : Scalar, Enum, InputObject # used in: variables (-> operations), arguments (-> fields/directives) | |
Output Types : Scalar, Enum, Object, Interface, Union | |
── Named Types & Wrapping types ── | |
Named Types : Scalar, Enum, Object, Interface, Union, InputObject | |
Wrapping Types : List, Not-Null | |
A wrapping type has an underlying named type, found by continually unwrapping the type until a named type is found. | |
── Built-In Scalar Types ── | |
Int, Float, String, Boolean, ID | |
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. | |
The ID scalar type represents a unique identifier, often used to refetch an object or as the key for a cache. | |
The ID type is serialized in the same way as a String; however, it is not intended to be human‐readable. | |
┌─────────────────┐ | |
──┤ Server Examples ├────────────────────────────────────────────────────────── | |
└─────────────────┘ | |
type Query { | |
hero(episode: Episode): Character | |
human(id: String!): Human | |
droid(id: String!): Droid | |
} | |
enum Episode { NEWHOPE, EMPIRE, JEDI } | |
interface Character { | |
id: String! | |
name: String | |
friends: [Character] | |
appearsIn: [Episode] | |
} | |
type Human implements Character { | |
id: String! | |
name: String | |
friends: [Character] | |
appearsIn: [Episode] | |
homePlanet: String | |
} | |
type Droid implements Character { | |
id: String! | |
name: String | |
friends: [Character] | |
appearsIn: [Episode] | |
primaryFunction: String | |
} | |
union SearchResult = Photo | Person | |
input Point2d { | |
x: Float | |
y: Float | |
} | |
── Directives ── | |
directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE # reason String allows Markdown | |
── Descriptions ── | |
Description strings occur immediately before the definition they describe, and allow Markdown. | |
"A simple GraphQL schema which is well described." | |
type Query { | |
"Translates a string from a given language into a different language." | |
translate( | |
"The original language that `text` is provided in." | |
fromLanguage: Language | |
"The translated language to be returned." | |
toLanguage: Language | |
"The text to be translated." | |
text: String | |
): String | |
} | |
┌─────────────────┐ | |
──┤ Client Examples ├────────────────────────────────────────────────────────── | |
└─────────────────┘ | |
{ hello } # 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. | |
fragment shred on SomeType { | |
# fields | |
} | |
query [Foo] ($foo: String) { | |
bar # simple scalar field | |
myAlias: baz(id: 57) # argument w/literal | |
berz(name: $foo) { # argument w/variable | |
...shred # fragment spread | |
... on SomeType { # inline fragment | |
# fields | |
} | |
} | |
bangerz(rand: 5) { | |
... @include(if: $expandedInfo) { # inline fragment wo/type condition and w/directive | |
firstName | |
lastName | |
birthday | |
} | |
} | |
} | |
mutation [Foo] { | |
doThing(thingID: 12345) { | |
result | |
} | |
} | |
subscription... | |
── Directives ── | |
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | |
directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | |
┌───────────┐ | |
──┤ Responses ├──────────────────────────────────────────────────────────────── | |
└───────────┘ | |
{ | |
# must not be present if operation failed before execution | |
# must be null if error encountered during execution that prevented a valid response | |
data: { ... } # object of root type (Query/Mutation) | |
# must not be present unless there are errors | |
# must be present and contain at least one error if 'data' entry not present | |
errors: [ | |
{ | |
message: "..." # required | |
locations: [ # optional; refers to request document | |
{ line: <line>, column: <column> }, | |
.... | |
] | |
path: [ "<level1>", ... ] # path of erroneous response field; ex: [ "hero", "heroFriends", 1, "name" ] | |
# path segments that represent fields should be strings, | |
# and path segments that represent list indices should be 0‐indexed integers | |
extensions: {} # optional | |
}, | |
... | |
] | |
extensions: {} # optional | |
} | |
┌──────────────────────────┐ | |
──┤ Errors & Non-Nullability ├───────────────────────────────────────────────── | |
└──────────────────────────┘ | |
• If an error is thrown while 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. | |
• 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 of a Non-Null type, then a field error is thrown. | |
The error must be added to the "errors" list in the response. | |
• If the field returns null because of an error which has already been added to the "errors" list in the response, | |
the "errors" list must not be further affected. | |
That is, only one error should be added to the errors list per field. | |
• Since Non-Null type fields cannot be null, field errors are propagated to be handled by the parent field. | |
If the parent field may be null then it resolves to null, | |
otherwise if it is a Non-Null type, the field error is further propagated to it’s parent field. | |
• If a List type wraps a Non-Null type, and one of the elements of that list resolves to null, | |
then the entire list must resolve to null. | |
If the List type is also wrapped in a Non-Null, the field error continues to propagate upwards. | |
• If all fields from the root of the request to the source of the field error return Non-Null types, | |
then the "data" entry in the response should be null. | |
┌───────────────┐ | |
──┤ Subscriptions ├──────────────────────────────────────────────────────────── | |
└───────────────┘ | |
If the operation is a subscription, the result is an event stream called the “Response Stream” | |
where each event in the event stream is the result of executing the operation for each new event on an underlying “Source Stream”. | |
Executing a subscription creates a persistent function on the server that maps an underlying Source Stream to a returned Response Stream. | |
subscription NewMessages { | |
newMessage(roomId: 123) { | |
sender | |
text | |
} | |
} | |
While the client is subscribed, whenever new messages are posted to chat room with ID “123”, | |
the selection for “sender” and “text” will be evaluated and published to the client, for example: | |
{ | |
"data": { | |
"newMessage": { | |
"sender": "Hagrid", | |
"text": "You're a wizard!" | |
} | |
} | |
} | |
Query and mutation operations are stateless, allowing scaling via cloning of GraphQL server instances. | |
Subscriptions, by contrast, are stateful and require maintaining the GraphQL document, variables, and other context over the lifetime of the subscription. | |
GraphQL subscriptions do not require any specific serialization format or transport mechanism. | |
Subscriptions specifies algorithms for the creation of a stream, the content of each payload on that stream, and the closing of that stream. | |
There are intentionally no specifications for message acknoledgement, buffering, resend requests, or any other quality of service (QoS) details. | |
Message serialization, transport mechanisms, and quality of service details should be chosen by the implementing service. | |
A Source Stream represents the sequence of events, each of which will trigger a GraphQL execution corresponding to that event. | |
Like field value resolution, the logic to create a Source Stream is application‐specific. | |
Each event in the underlying Source Stream triggers execution of the subscription selection set using that event as a root value. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
┌─────────────┐ https://graphql.github.io/graphql-spec/June2018/ | |
──┤ Spec T.O.C. ├────────────────────────────────────────────────────────────── | |
└─────────────┘ | |
○ Language Source Text • Document • Operations • Selection Sets | |
Fields • Arguments • Field Alias • Fragments | |
Input Values • Variables • Type References • Directives | |
○ Type System Type System Extensions • Schema • Descriptions | |
Types • Scalars • Objects • Interfaces • Unions • Enums | |
Input Objects • List • Non-Null • Directives | |
○ Introspection Reserved Names • Documentation • Deprecation | |
Type Name Introspection • Schema Introspection | |
○ Validation Documents • Operations • Fields • Arguments | |
Fragments • Values • Directives • Variables | |
○ Execution Executing Requests • Executing Operations | |
Executing Selection Sets • Executing Fields | |
○ Response Response Format • Serialization Format | |
┌─────────┐ | |
──┤ Grammar ├────────────────────────────────────────────────────────────────── | |
└─────────┘ | |
─── My Notation ─── | |
# single-line comments * -> list | |
"single-line strings" [] -> optional | |
"""multi-line strings""" a | b -> value set | |
Commas are optional throughout GraphQL so trailing commas are allowed and repeated commas do not represent missing values. | |
Name := /[_A-Za-z][_0-9A-Za-z]*/ | |
Document := Definition* | |
Definition := ExecutableDefinition | TypeSystemDefinition | TypeSystemExtension | |
────── Query ─────── ───────────────── Schema ───────────────── | |
── Query ── | |
ExecutableDefinition := OperationDefinition | FragmentDefinition | |
OperationDefinition := [OperationType [Name] [VariableDefinitions] [Directives]] SelectionSet | |
OperationType := 'query' | 'mutation' | 'subscription' | |
SelectionSet := { Selection* } | |
Selection := Field | FragmentSpread | InlineFragment | |
Field := [Alias] Name [Arguments] [Directives] [SelectionSet] | |
Alias := Name: | |
Arguments := ( Argument* ) | |
Argument := Name : Value | |
FragmentSpread := ...FragmentName [Directives] | |
InlineFragment := ... [TypeCondition] [Directives] SelectionSet | |
FragmentDefinition := 'fragment' FragmentName TypeCondition [Directives] SelectionSet | |
FragmentName := Name but not 'on' | |
TypeCondition := 'on' NamedType | |
Value := Variable | IntValue | FloatValue | StringValue | BooleanValue | NullValue | EnumValue | ListValue | ObjectValue | |
BooleanValue := 'true' | 'false' | |
NullValue := 'null' | |
EnumValue := Name but not 'true','false','null' | |
ListValue := [ [Value*] ] | |
ObjectValue := { [ObjectField*] } | |
ObjectField := Name : Value | |
VariableDefinitions := ( VariableDefinition* ) | |
VariableDefinition := Variable : Type [DefaultValue] | |
Variable := $Name | |
DefaultValue := = Value | |
Type := NamedType | ListType | NonNullType | |
NamedType := Name | |
ListType := [ Type ] | |
NonNullType := NamedType ! | ListType ! | |
Directives := Directive* | |
Directive := @Name [Arguments] | |
── Schema ── | |
TypeSystemDefinition := SchemaDefinition | TypeDefinition | DirectiveDefinition | |
TypeSystemExtension := SchemaExtension | TypeExtension | |
SchemaDefinition := 'schema' [Directives] { OperationTypeDefinition* } | |
SchemaExtension := 'extend schema' [Directives] { OperationTypeDefinition* } | |
'extend schema' Directives | |
OperationTypeDefinition := OperationType : NamedType | |
Description := StringValue | |
TypeDefinition := ScalarTypeDefinition | ObjectTypeDefinition | InterfaceTypeDefinition | UnionTypeDefinition | EnumTypeDefinition | InputObjectTypeDefinition | |
TypeExtension := ScalarTypeExtension | ObjectTypeExtension | InterfaceTypeExtension | UnionTypeExtension | EnumTypeExtension | InputObjectTypeExtension | |
ScalarTypeDefinition := [Description] 'scalar' Name [Directives] | |
ScalarTypeExtension := 'extend scalar' Name Directives | |
ObjectTypeDefinition := [Description] 'type' Name [ImplementsInterfaces] [Directives] [FieldsDefinition] | |
ObjectTypeExtension := 'extend type' Name [ImplementsInterfaces] [Directives] FieldsDefinition | |
'extend type' Name [ImplementsInterfaces] Directives | |
'extend type' Name ImplementsInterfaces | |
ImplementsInterfaces := 'implements' [&] NamedType | |
ImplementsInterfaces [&] NamedType | |
FieldsDefinition := { FieldDefinition* } | |
FieldDefinition := [Description] Name [ArgumentsDefinition] : Type [Directives] | |
ArgumentsDefinition := ( InputValueDefinition* ) | |
InputValueDefinition := [Description] Name : Type [DefaultValue] [Directives] | |
InterfaceTypeDefinition := [Description] 'interface' Name [Directives] [FieldsDefinition] | |
InterfaceTypeExtension := 'extend interface' Name [Directives] FieldsDefinition | |
'extend interface' Name Directives | |
UnionMemberTypes := '=' ['|'] NamedType | |
UnionMemberTypes | NamedType | |
UnionTypeDefinition := [Description] 'union' Name [Directives] [UnionMemberTypes] | |
UnionTypeExtension := 'extend union' Name [Directives] UnionMemberTypes | |
'extend union' Name Directives | |
EnumValuesDefinition := { EnumValueDefinition* } | |
EnumValueDefinition := [Description] EnumValue [Directives] | |
EnumTypeDefinition := [Description] 'enum' Name [Directives] [EnumValuesDefinition] | |
EnumTypeExtension := 'extend enum' Name [Directives] EnumValuesDefinition | |
'extend enum' Name Directives | |
InputFieldsDefinition := { InputValueDefinition* } | |
InputObjectTypeDefinition := [Description] 'input' Name [Directives] [InputFieldsDefinition] | |
InputObjectTypeExtension := 'extend input' Name [Directives] InputFieldsDefinition | |
'extend input' Name Directives | |
DirectiveDefinition := [Description] 'directive @' Name [ArgumentsDefinition] 'on' DirectiveLocations | |
DirectiveLocations := ['|'] DirectiveLocation | |
DirectiveLocations | DirectiveLocation | |
DirectiveLocation := ExecutableDirectiveLocation | TypeSystemDirectiveLocation | |
ExecutableDirectiveLocation := 'QUERY' | 'MUTATION' | 'SUBSCRIPTION' | 'FIELD' | 'FRAGMENT_DEFINITION' | 'FRAGMENT_SPREAD' | 'INLINE_FRAGMENT' | |
TypeSystemDirectiveLocation := 'SCHEMA' | 'SCALAR' | 'OBJECT' | 'FIELD_DEFINITION' | 'ARGUMENT_DEFINITION' | 'INTERFACE' | 'UNION' | | |
'ENUM' | 'ENUM_VALUE' | 'INPUT_OBJECT' | 'INPUT_FIELD_DEFINITION' | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
┌─────────────┐ | |
──┤ Meta-Fields ├────────────────────────────────────────────────────────────── | |
└─────────────┘ | |
Implicit - do not appear in the fields list. | |
type Query { | |
__schema: __Schema! | |
__type(name: String!): __Type | |
} | |
type <all Objects/Interfaces/Unions> { | |
__typename: String! | |
} | |
┌──────────────────────┐ | |
──┤ Introspection Schema ├───────────────────────────────────────────────────── | |
└──────────────────────┘ | |
type __Schema { | |
types: [__Type!]! | |
queryType: __Type! | |
mutationType: __Type | |
subscriptionType: __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 | |
locations: [__DirectiveLocation!]! | |
args: [__InputValue!]! | |
} | |
enum __DirectiveLocation { | |
QUERY | |
MUTATION | |
SUBSCRIPTION | |
FIELD | |
FRAGMENT_DEFINITION | |
FRAGMENT_SPREAD | |
INLINE_FRAGMENT | |
SCHEMA | |
SCALAR | |
OBJECT | |
FIELD_DEFINITION | |
ARGUMENT_DEFINITION | |
INTERFACE | |
UNION | |
ENUM | |
ENUM_VALUE | |
INPUT_OBJECT | |
INPUT_FIELD_DEFINITION | |
} | |
┌──────────┐ | |
──┤ Examples ├───────────────────────────────────────────────────────────────── | |
└──────────┘ | |
{ # Query | |
__type(name: "User") { | |
name | |
fields { | |
name type { name } | |
} | |
} | |
} | |
{ # Response | |
"__type": { | |
"name": "User", | |
"fields": [ | |
{ "name": "id", "type": { "name": "String" } }, | |
{ "name": "name", "type": { "name": "String" } }, | |
{ "name": "birthday", "type": { "name": "Date" } }, | |
] | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment