Schemas and Types

beginner
10 min

Schemas and Types

Everything in GraphQL starts with the schema. It is the contract that tells clients what they can ask for and tells the server what it must be able to answer. In this lesson you will learn the Schema Definition Language (SDL), the built-in scalar types, how to model objects and relationships, and how nullability works.

The Schema Definition Language

GraphQL schemas are written in a compact, language-agnostic syntax called SDL. Here is a small but complete schema for a blogging app:

graphql
type User { id: ID! name: String! email: String! age: Int posts: [Post!]! } type Post { id: ID! title: String! body: String! published: Boolean! author: User! } type Query { users: [User!]! post(id: ID!): Post }

Read posts: [Post!]! as: a non-null list of non-null Post objects. The schema is declarative; it says nothing about databases or how data is fetched. That separation is what lets a GraphQL layer sit in front of SQL, MongoDB, REST services, or all three at once.

The Five Built-in Scalars

Scalars are the leaves of every query, the points where the graph ends in concrete values:

  • Int - signed 32-bit integer
  • Float - double-precision floating point
  • String - UTF-8 text
  • Boolean - true or false
  • ID - a unique identifier, serialized as a string but signaling "do not display this to humans"

Need dates or JSON? GraphQL lets you define custom scalars like scalar DateTime, with serialization logic supplied by your server. Libraries such as graphql-scalars ship dozens of ready-made ones.

Object Types and Relationships

Object types are where GraphQL earns the "graph" in its name. In the schema above, User has posts and Post has author, a circular relationship that would be awkward in REST but is natural here. Clients can traverse edges in either direction:

graphql
query { post(id: "7") { title author { name posts { title } } } }

Nullability: The ! Modifier

By default every field in GraphQL is nullable. Appending ! makes it non-null, and the server guarantees it will never return null for that field. Choose deliberately:

  • Make a field non-null only if it can never be missing, even during partial failures.
  • Keep fields nullable when they come from a service that might be down; a null field is recoverable, but a null on a non-null field destroys its whole parent object in the response.

Root Types: Query, Mutation, Subscription

Three special object types define the entry points of your API. Query for reads, Mutation for writes, and Subscription for real-time streams. Every operation a client sends must start at a field on one of these roots. A schema must have a Query type; the other two are optional.

Documenting Your Schema

SDL supports descriptions using triple quotes, and they surface automatically in tools like GraphiQL:

graphql
"""A registered member of the site.""" type User { """Display name, unique per account.""" name: String! }

Well-described schemas are self-documenting APIs; invest in them early.

Key Takeaways

  • The schema, written in SDL, is a typed contract independent of any data source.
  • Five built-in scalars cover the basics; custom scalars handle dates, JSON, and more.
  • Object types link to each other, forming a traversable graph.
  • ! marks non-null; use it thoughtfully because non-null failures cascade upward.
  • Query, Mutation, and Subscription are the only entry points clients can use.

Next lesson: Queries, where we put this schema to work and ask for exactly what we need.

Schemas and Types - GraphQL | CodeYourCraft | CodeYourCraft