GraphQL is innovative, and it offers some interesting advantages:
- Selectively request the data needed
- Get many resources in a single query
- Evolve your API without versions
- Built-in type-system
## The GraphQL schema
A **schema** is like a contract between the server and the client. 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.
At its heart, 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_. For example, a `Song` object type could have an `song` field of type `Song`.
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 contained fields:
```graphql
type SpaceCat {
# Fields go here
}
```
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
Unlike Javascript objects (which look very similar), fields are not separated by commas.
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:
```graphql
type SpaceCat {
name: String!
age: Int
missions: [Mission]
}
```
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 certain tools 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. Triple "double quotes" allow you to add line breaks for clearer formatting of lengthier comments.
```graphql
"""
Adventurous Feline exploring the universe
"""
type SpaceCat {
"Name of the cat"
name: String!
age: Int
missions: [Mission]
}
```
### The `Query` type
The `Query` type is defined like any other object type:
```graphql
type Query {
# Fields go here
}
```
The fields of this type are **entry points** into the rest of our schema. These are the top-level fields that our client can query for.