Rules
February 10, 2023 · View on GitHub
The GraphQL Standard defines a set of rules which MUST be followed.
Each rule has a badge explaining its status in the linting tool. The following badges are used:
The difference is if it is automatically fixed, only checked or completely missing.
CamelCase field name 
All field names MUST be camelCase.
When creating a field under any node type, the field names should always be written in camelCase.
❌ Invalid
type user {
email_address: String!
FullName: String!
DAY_OF_BIRTH: Date!
}
✅ Valid
type user {
emailAddress: String!
fullName: String!
dayOfBirth: Date!
}
Suffix input type with Input 
All input types MUST be suffixed with Input
When creating an input type node, the name should always be suffixed with Input.
❌ Invalid
input Review {
stars: Int!
commentary: String
}
✅ Valid
input ReviewInput {
stars: Int!
commentary: String
}
Description required for all nodes 
All nodes (arguments, fields, queries, types, etc.) MUST have a description.
When a new node of any type is created a description shall be available for it.
❌ Invalid
type Invoice {
id: ID! @globalId
number: String!
}
✅ Valid
"""
An Invoice that is stored.
"""
type Invoice {
"""
The global identifier for the invoice.
"""
id: ID! @globalId
"""
A number referencing the invoice.
This is usually printed on the invoice itself and should be used by booking system and finance departments.
The format is a human readable format.
"""
number: String!
}
ID fields are non-nullable 
All fields named ID (or id) MUST be non-nullable.
When declaring an ID field, this should always have a value as it is the primary key of the type.
❌ Invalid
type User {
id: ID
}
✅ Valid
type User {
id: ID!
}
Lists are non-nullable 
All fields with a list value MUST be non-nullable when field definition is output type.
When declaring a list field, the value MUST always be a list (either empty, or populated) on output types.
It is allowed to have list fields on input types which are nullable.
❌ Invalid
type Company {
"""
The lack of non-nullable enforcement means that this can either be `[]`, `null`, or a populated list.
This means that end-users would need to implement checks for both `null` and an empty list.
"""
invoices: [Invoice!]
}
✅ Valid
type Company {
"""
The use of non-nullable enforcement means that the value will only ever be `[]` or a populated list.
"""
invoices: [Invoice!]!
}
input CompanyInput {
owners: [String!]
}
Mutation have one input argument field 
All mutations MUST have a single input object named input.
❌ Invalid
# Mutation with multiple input variables
mutation ($currency: CurrencyType!, $company: Company!) {
updateInvoiceCurrency(company: $company, currency: $currency) {
title
company {
name
}
}
}
✅ Valid
# Input Type
input UpdateInvoiceCurrencyInput {
currency: CurrencyType!
company: Company!
}
# Request mutation with single input variable named "input"
mutation ($input: UpdateInvoiceCurrencyInput!) {
updateInvoiceCurrency($input: UpdateInvoiceCurrencyInput!) {
currency
value
}
}
Types in list are non-nullable 
All types inside fields with a list value MUST be non-nullable.
❌ Invalid
type Company {
"""
The lack of non-nullable enforcement means that this can either be `[]`, `[null]`, or a populated list of 'Invoice' types.
This means that end-users would need to implement checks for both a list containing `null` and an empty list.
"""
invoices: [Invoice]!
}
✅ Valid
type Company {
"""
The use of non-nullable enforcement means that the value will only ever be `[]` or a populated list of type 'Invoice'.
"""
invoices: [Invoice!]!
}
Pascal case object types 
All object types MUST use pascal case.
❌ Invalid
type userInvoice {
}
✅ Valid
type UserInvoice {
}
UPPER_SNAKE enum cases 
All enum cases MUST use upper snake case.
❌ Invalid
enum Status {
case Active
case fulfilled
case in_progress
}
✅ Valid
enum Status {
case ACTIVE
case FULFILLED
case IN_PROGRESS
}