Schema naming conventions
Conventions for types, fields, and arguments
High-level guidance
- Regardless of your chosen conventions, be consistent across the entire schema.
- Be specific with names—don't "land grab" names with broad applicability.
- Avoid acronyms, initialisms, and abbreviations.
Casing
Use camelCase
for field names, argument names, and directive names:
type Query {myCamelCaseFieldNames(myArgumentName: String): String}directive @myDirective on FIELD
Use PascalCase
for type names:
type MyType { ... }enum MyEnum { ... }interface MyInterface { ... }union MyUnion = ...scalar MyScalar
Use SCREAMING_SNAKE_CASE
for enum values:
enum MyEnum {VALUE_ONEVALUE_TWO}
Field names
Avoid verb prefixes like get
or list
on query (read) fields:
type Query {# ❌ incorrectgetProducts: [Product]# ✅ correctproducts: [Product]}
This creates consistency between root fields and nested fields:
# ❌ incorrectquery Products {getProducts {idgetReviews {content}}}# ✅ correctquery Products {products {idreviews {content}}}
Start mutation fields with a verb:
type Mutation {# ❌ incorrectcustomerAdd(input: AddCustomerInput): AddCustomerPayload!# ✅ correctaddCustomer(input: AddCustomerInput): AddCustomerPayload!}
Type names
Use the suffix Input
when naming input types:
input AddCustomerInput {name: String!}
Use a consistent suffix like Response
or Payload
when naming output types returned from mutations:
type Mutation {addCustomer(input: AddCustomerInput!): AddCustomerResponse!}type AddCustomerResponse {success: Boolean!}
Additional considerations
Enforcing conventions
Use GraphQL-ESLint's naming-convention rule to catch violations.
Namespacing
When resolving naming conflicts between different domains, we recommend using one of the following:
PascalCase Prefix
type StoreCustomer { ... }type SiteCustomer { ... }
Single_Underscore Prefix
type Store_Customer { ... }type Site_Customer { ... }