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 aListing
type - Add our DGS 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:
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: IDname: Stringmass: IntnamesOfMoons: [String]}
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: IntnamesOfMoons: [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.
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: Intgalaxy: Galaxy}type Galaxy {id: ID!name: String!yearDiscovered: Int}
This relationship lets us query details about a 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 descriptionwith 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}
Practice
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
orInt
) or return other object types.
Up next
With that final point covered, let's jump into the next lesson and build our schema!
Share your questions and comments about this lesson
This course is currently in
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.