Working with Object Types
1. Creating Object Types
| Element | Syntax |
| Declaration | type TypeName { ... } |
| Field | fieldName: ReturnType |
| With args | posts(first: Int): [Post!]! |
| Implements | type User implements Node { id: ID! } |
Example: Object type
type Post {
id: ID!
title: String!
body: String!
author: User!
comments(first: Int = 10): [Comment!]!
createdAt: DateTime!
}
2. Defining Fields with Types
| Field Type | Example | Notes |
| Scalar | title: String | Leaf value |
| Enum | status: OrderStatus | Fixed values |
| Object | author: User | Nested selection |
| List | tags: [String!]! | Ordered collection |
| Interface/Union | node: Node | Polymorphic |
3. Making Fields Required
| Modifier | Meaning |
String | Nullable string |
String! | Non-null; resolver must not return null |
[String] | Nullable list of nullable strings |
[String!] | Nullable list, items required |
[String!]! | Required list of required strings |
4. Making Fields Nullable
| Pattern | When |
| Default nullable | Resolver may fail without aborting parent |
| Use null | Field not applicable / unknown |
| Empty list vs null | Prefer [] for "no items" |
Note: Default to nullable; mark ! only when truly guaranteed. Non-null errors propagate up to first nullable ancestor.
5. Defining Field Arguments
Example: Arguments with defaults
type Query {
posts(
first: Int = 20
after: String
orderBy: PostOrder = { field: CREATED_AT, direction: DESC }
filter: PostFilter
): PostConnection!
}
| Form | Example |
| Required arg | id: ID! |
| Optional arg | first: Int |
| Default value | first: Int = 20 |
| Input object arg | filter: PostFilter |
6. Setting Default Argument Values
| Rule | Detail |
| Literal only | Default must be a constant literal |
| Applied when | Argument omitted OR explicitly null on nullable arg |
| Required + default | first: Int! = 10 — caller may still omit |
7. Using Type References
| Form | Note |
| Forward reference | Allowed; SDL is order-independent |
| Circular | Supported (User.posts ↔ Post.author) |
| Self-reference | Allowed (Tree.children: [Tree!]!) |
8. Implementing Interfaces
Example: Implements Node
interface Node { id: ID! }
type User implements Node {
id: ID!
email: String!
}
| Rule | Detail |
| Field set | Must include all interface fields with compatible types |
| Args | Must accept all interface args |
| Multiple | implements Node & Timestamped |
9. Creating Abstract Types
| Kind | When to use |
| Interface | Shared fields across implementing types |
| Union | Heterogeneous result, no shared fields |
| Pattern | Example |
| Co-locate | User.graphql contains User, UserConnection, UserEdge, UserInput |
| Group by feature | billing/, auth/, catalog/ folders |
| Shared | common/scalars.graphql, common/interfaces.graphql |