Odyssey

Intro to GraphQL with TypeScript & Apollo Server

Course overview and setupGraphQL basicsSchema definition language (SDL)Building the schemaApollo ServerApollo Sandbox ExplorerThe listings REST APIResolversCodegenQuerying real dataQuery argumentsAdding the Amenity typeResolver chainsMutations
3. Schema definition language (SDL)
3m

Overview

To begin putting the pieces of our GraphQL server together, we need to take a closer look at Schema Definition Language, or SDL. This is the syntax that lets us actually define object types and their fields in a way that the GraphQL server can understand.

In this lesson, we will:

  • Explore SDL syntax
  • Define a basic schema with a Query and a Listing type
  • Add our dependencies

đź“„ Exploring SDL

You can think of our server's schema as a contract between the server and any client asking for data. It defines what a GraphQL API can and can't do, and how clients can request or change data. It's an abstraction layer that provides flexibility to consumers while hiding backend implementation details.

In practice, a schema is a collection of object types that contain fields. Each field has a type of its own. A field's type can be scalar (such as an Int or a String), or it can be another object type. We'll see an example of this shortly.

GraphQL type syntax

We declare a type using the type keyword, followed by the name of the type (PascalCase is best practice), then opening brackets to hold its fields:

Example GraphQL type
type Planet {
}

Fields are declared by their name (camelCase), a colon, and then the type of the field (scalar or object). A field can also contain a list, indicated by square brackets:

type Planet {
id: ID
name: String
mass: Int
namesOfMoons: [String]
}

Take a closer look at the namesOfMoons field; it returns a list of String types.

namesOfMoons: [String]

This representation lets us envision the shape the underlying namesOfMoons data might take:

{
"namesOfMoons": [
"Calypso",
"Argo XIV",
"Telemachus-5"
]
}

In a future iteration of the schema, we might decide to use each name to build a separate Moon type, which would let us describe a particular moon's data in greater detail. For now, this simple example is intended to illustrate the purpose of the GraphQL list syntax.

Nullability in GraphQL

In addition, we can indicate whether each field value is nullable or non-nullable. If a field should never be null, we add an exclamation mark after its type:

type Planet {
id: ID!
name: String!
mass: Int
namesOfMoons: [String]
}

This syntax states that it's not valid for a Planet to return null for the id or name fields; we require them to return a value that matches their specified data type. By contrast, we'll permit mass and namesOfMoons to be null if we have no data to return.

One approach is to make the schema reflect our "business" domain rules.

type Planet {
id: ID! # REQUIRED!
name: String! # REQUIRED!
mass: Int
namesOfMoons: [String]
}

Considering the Planet type above, we'd find it difficult to work with this data if we lacked a unique identifier (the id field) or name. Allowing either of those fields to return null doesn't make sense from our "business" point of view.

We might not feel as strongly about namesOfMoons or mass, however: after all, the planet might not have any moons, and we might not know the mass of a planet!

Working with multiple object types

GraphQL also gives us the ability to represent relationships between objects. Take these two object types for example:

type Planet {
id: ID!
name: String!
mass: Int
}
type Galaxy {
id: ID!
name: String!
yearDiscovered: Int
}

Suppose we want to represent the relationship between planets and galaxies. For example, we might want each planet to indicate the galaxy it belongs to. How do we represent this in GraphQL?

In this case, we could update Planet with a field that returns another object type; one that specifies which galaxy it belongs to.

type Planet {
id: ID!
name: String!
mass: Int
galaxy: Galaxy
}
type Galaxy {
id: ID!
name: String!
yearDiscovered: Int
}

This relationship lets us query details about an planet, then query further details about the galaxy it's found in. We can ask more complex questions of our data—like "What's the mass of this planet, and what is the name of the galaxy it belongs to?"—and get all of the answers in one neatly-bundled response.

Documenting the schema

All right, last thing before we start writing our schema: descriptions.

It's good practice to document your schema, in the same way that it's helpful to comment your code. It makes it easier for your teammates (and future you) to make sense of what's going on. It also allows tools like the GraphOS Studio Explorer to guide API consumers on what they can achieve with your API right when and where they need it.

To do that, the SDL lets you add descriptions to both types and fields by writing strings (in quotation marks) directly above them.

"I'm a regular description"

Triple "double quotes" allow you to add line breaks for clearer formatting of lengthier comments.

"""
I'm a block description
with a line break
"""

Here's what a fully-documented GraphQL type might look like.

"Astronomical information for a single planet."
type Planet {
"The ID for the planet"
id: ID!
"The planet's name"
name: String!
"The total estimated mass of the planet (in kg)"
mass: Int
"The galaxy the planet is located in"
galaxy: Galaxy
}

With that final point covered, let's build our schema!

Practice

Which of the following are valid field types?
What does an exclamation mark after a field's type indicate?
Code Challenge!

Define a Moon type with the following fields: name of type String (non-null), mass of type Int, and missions of type List of Mission.

Key takeaways

  • The fields of the Query type are entry points into our schema. These are the top-level fields that a GraphQL consumer can query for.
  • GraphQL object types define fields we can query for data. These fields can return scalar data (such as String or Int) or return other object types.

Up next

With that final point covered, let's jump into the next lesson and build our schema!

Previous
Next

Share your questions and comments about this lesson

Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.

              GraphQL server

              A server that contains a GraphQL schema and can resolve client-requested operations that are executed against that schema.

              SDL

              GraphQL's schema definition language (SDL). The syntax for writing GraphQL schemas. All GraphQL APIs can use SDL to represent their schema, regardless of the API's programming language.

              object types

              A type in a GraphQL schema that has one or more fields. User is an object type in the following example:

              type User {
              name: String!
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL server

              A server that contains a GraphQL schema and can resolve client-requested operations that are executed against that schema.

              SDL

              GraphQL's schema definition language (SDL). The syntax for writing GraphQL schemas. All GraphQL APIs can use SDL to represent their schema, regardless of the API's programming language.

              contract

              A mechanism for delivering different subsets of your supergraph to different consumers.

              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              Fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              scalar

              A "base" type that resolves to a single value. GraphQL includes the following scalar types by default: Int, Float, String, Boolean, and ID.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              object types

              A type in a GraphQL schema that has one or more fields. User is an object type in the following example:

              type User {
              name: String!
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              object type

              A type in a GraphQL schema that has one or more fields. User is an object type in the following example:

              type User {
              name: String!
              }
              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              document

              A file or request string that contains one or multiple definitions of a GraphQL type system and can be interpreted by a GraphQL execution engine.

              GraphOS Studio Explorer

              A powerful web IDE for creating, running, and managing GraphQL operations. It's also available in a Sandbox mode that doesn't require an Apollo account.

              SDL

              GraphQL's schema definition language (SDL). The syntax for writing GraphQL schemas. All GraphQL APIs can use SDL to represent their schema, regardless of the API's programming language.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              GraphQL

              An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.

              object types

              A type in a GraphQL schema that has one or more fields. User is an object type in the following example:

              type User {
              name: String!
              }
              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              scalar

              A "base" type that resolves to a single value. GraphQL includes the following scalar types by default: Int, Float, String, Boolean, and ID.

              object types

              A type in a GraphQL schema that has one or more fields. User is an object type in the following example:

              type User {
              name: String!
              }

              NEW COURSE ALERT

              Introducing Apollo Connectors

              Connectors are the new and easy way to get started with GraphQL, using existing REST APIs.

              Say goodbye to GraphQL servers and resolvers—now, everything happens in the schema!

              Take the course