To make it easy to understand the capabilities of a server, GraphQL implements a human-readable schema syntax known as its Schema Definition Language, or "SDL". The SDL is used to express the _types_ available within a schema and how those types relate to each other.
At first glance the SDL may appear to be similar to JavaScript, but this GraphQL-specific syntax must be stored as a `String`. Right now, we'll focus on explaining SDL and then go into examples of using it within JavaScript later on.
In a simple example involving books and authors, the SDL might declare:
It's important to note that these declarations express the _relationships_ and the _shape_ of the data to return, not where the data comes from or how it might be stored - which will be covered outside the SDL.
By drawing these logical connections in the schema definition, we can allow the client (which is often a human developer, designing a front-end) to see what data is available and request it in a single optimized query.
GraphQL clients (such as [Apollo Client](/docs/react)) benefit from the precision of GraphQL operations, especially when compared to traditional REST-based approaches, since they can avoid over-fetching and stitching data, which are particularly costly on slow devices or networks.
In order to define what queries are possible on a server, the `Query` type is used within the SDL. The `Query` type is one of many root-level types which defines functionality (it doesn't actually trigger a query) for clients and acts as an entry-point to other more specific types within the schema.
Using the books and author example we created in the SDL example of the last section, we can define multiple independent queries which are available on a server:
In this `Query` type, we define two types of queries which are available on this GraphQL server:
*`getBooks`: which returns a list of `Book` objects.
*`getAuthors`: which returns a list of `Author` objects.
Those familiar with REST-based APIs would normally find these located on separate end-points (e.g. `/api/books` and `/api/authors`), but GraphQL allows them to be queried at the same time and returned at once.
As mentioned in the previous section, the structure in which types are organized in the SDL is important because of the relationships it creates. When a client makes a query to the server, the server will return results in a shape that matches that of the query.
Based on the SDL defined above, a client could request a list of all books _and_ a separate list of all authors by sending a single `query` with exactly what it wishes to receive in return:
While having two separate lists—a list of books and a list of authors—might be useful for some purposes, a separate desire might be to display a single list of books which includes the author for each book.
Mutations are operations sent to the server to create, update or delete data. These are comparable to the `PUT`, `POST`, `PATCH` and `DELETE` verbs on REST-based APIs.
Much like how the `Query` type defines the entry-points for data-fetching operations on a GraphQL server, the root-level `Mutation` type specifies the entry points for data-manipulation operations.
For example, when imagining a situation where the API supported adding a new `Book`, the SDL might implement the following `Mutation` type:
This implements a single `addBook` mutation which accepts `title` and `author` as arguments (both `String` types). We'll go further into arguments (also known as "input types") in [types](../schemas/types.html), but the important thing to note here is that this mutation will return the newly-created `Book` object.
The `Book` object will match the previously-created `Book` type (from above) and, much like the `Query` type, we specify the fields to include in the return object when sending the `mutation`:
Multiple mutations may be sent in the same request, however they will be executed in the order they are provided (in series), in order to avoid race-conditions within the operation.
Introspection is an **optional** feature, enabled by default during development, which allows clients to automatically discover the types implemented within a GraphQL schema.