Scalar and Object Types
Every field in a GraphQL schema ultimately resolves to a scalar type at its leaves — a concrete, indivisible value like a string or number — even when the field itself returns a complex object type. GraphQL ships with five built-in scalars: String for UTF-8 text, Int for signed 32-bit integers, Float for signed double-precision floating point numbers, Boolean for true/false, and ID for a unique identifier that is serialized as a string but signals semantic intent, such as being used as a cache key or lookup argument rather than displayed text.
Cricket analogy: A scalar is like a single stat on a scorecard — the number 87 for runs scored is an indivisible value, unlike the batter's full profile which is a composite object type.
The Five Built-In Scalars
The ID scalar deserves special attention because it looks identical to String on the wire — both serialize as JSON strings — but it carries semantic meaning that tooling relies on: normalized caches in Apollo Client and Relay use a type's id field combined with its type name to uniquely identify and deduplicate objects across different queries, and GraphQL's Relay-style global object identification convention is built entirely around a well-defined ID field. Choosing Int versus Float also matters for precision-sensitive domains: a warehouse inventory count should be Int, while a geographic coordinate is typically modeled as Float, though many schemas use a custom Decimal or Money scalar instead of Float for currency to avoid floating-point rounding errors.
Cricket analogy: Treating a player's ID scalar like their unique BCCI registration number rather than just their display name lets a stats app deduplicate 'V Kohli' records pulled from different match feeds into one player object.
scalar DateTime
enum OrderStatus {
PENDING
SHIPPED
DELIVERED
CANCELLED
}
type Order {
id: ID!
placedAt: DateTime!
status: OrderStatus!
totalCents: Int!
}Custom Scalars and Enums
Beyond the five built-ins, GraphQL lets servers define custom scalars for domain-specific values that need their own serialization logic, the most common example being a DateTime scalar for ISO-8601 timestamps; implementing one requires providing serialize (converting the internal value to a JSON-safe form for the response), parseValue (converting an incoming JSON value from a variable), and parseLiteral (converting an inline value written directly in the query text) functions. Enums are a related but distinct concept: an enum type restricts a field to one of a fixed set of named values, such as enum OrderStatus { PENDING, SHIPPED, DELIVERED, CANCELLED }, giving both the schema and generated client types a closed, self-documenting set of valid options instead of an unconstrained string.
Cricket analogy: A custom DateTime scalar for a match's toss time is like the ICC standardizing all match timestamps to UTC in official records, while an enum for MatchResult (WON, LOST, TIED, NO_RESULT) mirrors cricket's own fixed, official set of outcome labels.
Implementing a custom scalar requires three functions — serialize, parseValue, and parseLiteral — but you rarely need to write these from scratch: libraries like graphql-scalars already ship battle-tested implementations for DateTime, EmailAddress, URL, and dozens of other common domain types.
Object Types Build the Graph
Object types become genuinely powerful when their fields reference other object types rather than only scalars: a Book type can have an author field of type Author, and Author can have a books field of type [Book!]!, creating a graph with a real cycle that a client can traverse in either direction within a single query — fetching a book's author and that author's other books in one round trip. This is the structural feature GraphQL is named for, but it also means a resolver for a nested object field runs independently for each parent item, so naively resolving each Book's Author with a separate database call inside a loop produces the classic N+1 query problem, which is why production servers typically batch and cache these lookups using a tool like DataLoader.
Cricket analogy: A Player type with a team field of type Team, and Team with a players field of type [Player!]!, lets a client fetch Kohli's team and then that team's full squad in one traversal, mirroring how a cricket almanac cross-references player and team pages.
Resolving nested object fields naively — issuing one database query per item inside a loop, such as fetching each Book's Author one at a time — produces the classic N+1 query problem. Batch and cache these lookups per request with a tool like DataLoader to collapse them into a single query.
- Scalars are indivisible leaf values; GraphQL's five built-ins are String, Int, Float, Boolean, and ID.
- ID looks like String on the wire but signals semantic intent used by caching and global object identification.
- Custom scalars (like DateTime or Money) need serialize, parseValue, and parseLiteral functions, often provided by libraries like graphql-scalars.
- Enums restrict a field to a fixed, named set of values, giving a closed and self-documenting alternative to plain strings.
- Object types reference other object types, forming the actual graph structure GraphQL is named for.
- Naively resolving nested object fields in a loop causes the N+1 query problem; DataLoader batches and caches these lookups.
Practice what you learned
1. Which of the following is NOT one of GraphQL's five built-in scalar types?
2. How does the ID scalar differ from String on the wire?
3. What three functions must a custom scalar implementation typically provide?
4. What problem occurs when a resolver naively fetches each parent item's related object with a separate database call inside a loop?
5. What advantage does an enum type provide over a plain String field?
Was this page helpful?
You May Also Like
The GraphQL Schema
How GraphQL's Schema Definition Language describes types, fields, and operations as the contract between client and server.
What Is GraphQL?
An introduction to GraphQL as a query language and runtime for APIs, and the problems it was designed to solve.
Setting Up a GraphQL Server
A hands-on walkthrough of standing up a GraphQL server with Apollo Server, from schema and resolvers to running your first query.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics