📖 Guide
GraphQL Reference
Complete GraphQL reference — schema definition, types, queries, mutations, directives, fragments, and common patterns.
69 commands across 11 categories
Schema DefinitionScalar TypesObject TypesInput TypesEnumsInterfaces & UnionsDirectivesVariablesFragmentsIntrospectionCommon Patterns
Schema Definition
| Command | Description |
|---|---|
type Query {
users: [User!]!
user(id: ID!): User
} | Define root Query type — entry point for reads |
type Mutation {
createUser(input: CreateUserInput!): User!
deleteUser(id: ID!): Boolean!
} | Define root Mutation type — entry point for writes |
type Subscription {
messageAdded(channelId: ID!): Message!
} | Define root Subscription type — real-time data |
schema {
query: Query
mutation: Mutation
subscription: Subscription
} | Explicit schema definition (optional, auto-inferred from type names) |
"""User account in the system"""
type User { ... } | Schema documentation using description strings |
# Comment
type User { ... } | Code comments (not included in introspection) |
Scalar Types
| Command | Description |
|---|---|
String | UTF-8 character sequence |
Int | Signed 32-bit integer |
Float | Signed double-precision floating-point value |
Boolean | true or false |
ID | Unique identifier — serialized as String |
scalar DateTime | Custom scalar type declaration |
scalar JSON | Custom scalar for arbitrary JSON data |
scalar URL | Custom scalar for URL validation |
Object Types
| Command | Description |
|---|---|
type User {
id: ID!
name: String!
email: String!
age: Int
posts: [Post!]!
} | Object type with required (!) and optional fields |
String! | Non-null — field can never return null |
[String] | Nullable list of nullable strings |
[String!]! | Non-null list of non-null strings (most common for lists) |
[String!] | Nullable list of non-null strings |
type Post {
id: ID!
title: String!
author: User!
comments(first: Int = 10): [Comment!]!
} | Field with arguments and default value |
type Query {
users(limit: Int, offset: Int, sort: SortOrder): [User!]!
} | Query with multiple optional arguments |
Input Types
| Command | Description |
|---|---|
input CreateUserInput {
name: String!
email: String!
age: Int
} | Input type for mutation arguments |
input UpdateUserInput {
name: String
email: String
age: Int
} | Input type with all optional fields (partial update) |
input PaginationInput {
page: Int! = 1
perPage: Int! = 20
} | Input type with default values |
input FilterInput {
field: String!
operator: FilterOperator!
value: String!
} | Input type for dynamic filtering |
mutation {
createUser(input: CreateUserInput!) {
id
name
}
} | Using an input type in a mutation |
Enums
| Command | Description |
|---|---|
enum Role {
ADMIN
USER
MODERATOR
} | Enum type — restricted set of values |
enum SortOrder {
ASC
DESC
} | Enum for sort direction |
enum Status {
DRAFT
PUBLISHED
ARCHIVED
} | Enum for content status |
type User {
role: Role!
} | Using an enum as a field type |
query {
users(sort: ASC) { name }
} | Passing enum value in a query |
Interfaces & Unions
| Command | Description |
|---|---|
interface Node {
id: ID!
}
type User implements Node {
id: ID!
name: String!
} | Interface — shared fields across types |
interface Timestamped {
createdAt: DateTime!
updatedAt: DateTime!
}
type Post implements Node & Timestamped {
id: ID!
createdAt: DateTime!
updatedAt: DateTime!
title: String!
} | Implementing multiple interfaces |
union SearchResult = User | Post | Comment | Union type — value can be one of several types |
query {
search(query: "hello") {
... on User { name }
... on Post { title }
... on Comment { body }
}
} | Querying a union type with inline fragments |
query {
node(id: "123") {
__typename
... on User { name }
... on Post { title }
}
} | Use __typename to identify the concrete type |
union Timeline = Post | Photo | Video | Link | Union for a feed/timeline of mixed content |
Directives
| Command | Description |
|---|---|
@deprecated(reason: "Use newField instead") | Mark a field as deprecated |
query ($withDetails: Boolean!) {
user {
name
email @include(if: $withDetails)
}
} | @include — conditionally include a field |
query ($minimal: Boolean!) {
user {
name
bio @skip(if: $minimal)
}
} | @skip — conditionally skip a field |
@specifiedBy(url: "https://tools.ietf.org/html/rfc3339") | Link scalar to its specification |
directive @auth(requires: Role!) on FIELD_DEFINITION | Custom directive definition |
type Mutation {
deleteUser(id: ID!): Boolean! @auth(requires: ADMIN)
} | Using a custom directive on a field |
directive @cacheControl(maxAge: Int!) on FIELD_DEFINITION | OBJECT | Custom directive on multiple locations |
Variables
| Command | Description |
|---|---|
query GetUser($id: ID!) {
user(id: $id) {
name
email
}
} | Query with a required variable |
query GetUsers($limit: Int = 10, $offset: Int = 0) {
users(limit: $limit, offset: $offset) {
name
}
} | Variables with default values |
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
}
} | Mutation with input variable |
{
"id": "123",
"input": { "name": "Alice", "email": "alice@example.com" }
} | Variable values JSON (sent alongside query) |
query ($ids: [ID!]!) {
users(ids: $ids) { name }
} | List variable type |
Fragments
| Command | Description |
|---|---|
fragment UserFields on User {
id
name
email
avatar
} | Named fragment — reusable field selection |
query {
user(id: "1") { ...UserFields }
admin: user(id: "2") { ...UserFields }
} | Using a fragment with spread syntax |
query {
search(query: "hello") {
... on User { name email }
... on Post { title body }
}
} | Inline fragments — type-specific fields without named fragment |
fragment PostWithAuthor on Post {
title
body
author {
...UserFields
}
} | Nested fragments — compose fragments together |
fragment Recursive on Comment {
id
body
replies {
id
body
}
} | Fragment for nested/recursive structures |
Introspection
| Command | Description |
|---|---|
{ __schema { types { name } } } | List all types in the schema |
{ __schema { queryType { name } mutationType { name } } } | Get root type names |
{ __type(name: "User") { name fields { name type { name kind } } } } | Introspect a specific type and its fields |
{ __type(name: "User") { fields { name description isDeprecated deprecationReason } } } | Check for deprecated fields |
{ __schema { directives { name description locations args { name } } } } | List all available directives |
query { __typename } | Get the typename of the current query root |
{ __schema { types { name kind description } } } | Full type list with kinds (OBJECT, SCALAR, ENUM, etc.) |
Common Patterns
| Command | Description |
|---|---|
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
type UserEdge {
node: User!
cursor: String!
}
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
totalCount: Int!
} | Relay-style cursor pagination |
type Query {
users(first: Int, after: String, last: Int, before: String): UserConnection!
} | Connection-based pagination query |
type Query {
users(page: Int! = 1, perPage: Int! = 20): UserPage!
}
type UserPage {
items: [User!]!
total: Int!
page: Int!
totalPages: Int!
} | Offset-based pagination (simpler alternative) |
type MutationResponse {
success: Boolean!
message: String
user: User
errors: [FieldError!]
}
type FieldError {
field: String!
message: String!
} | Standardized mutation response with error handling |
interface Node {
id: ID!
}
type Query {
node(id: ID!): Node
} | Node interface pattern — fetch any entity by global ID |
type Query {
viewer: User!
} | Viewer pattern — current authenticated user as entry point |
extend type Query {
products: [Product!]!
} | Schema extension — add fields to existing types (federation/modular schemas) |
type Subscription {
onUserCreated: User!
onPostUpdated(id: ID!): Post!
} | Subscription patterns for real-time updates |
📖 Free, searchable command reference. Bookmark this page for quick access.