Let's jump into how GraphQL works, and the components that bring a GraphQL server to life!
In this lesson, we will:
- Explore the journey of how a client requests data and how a GraphQL server retrieves it
- Learn about the components that make up a GraphQL server
Journey of a GraphQL operation
Let's imagine our frontend needs to fetch data for a particular page.
To get that data, it sends a GraphQL operation to our GraphQL server. The app shapes the operation as a string that defines the selection set of fields it needs. Then, it sends that operation to the server in an HTTP
When our server receives the HTTP request, it first extracts the string with the GraphQL operation. It parses and transforms it into something it can better manipulate: a tree-structured document called an AST (Abstract Syntax Tree). With this AST, the server validates the operation against the types and fields in our schema.
If anything is off (e.g. a requested field is not defined in the schema or the operation is malformed), the server throws an error and sends it right back to the app.
In this case, the operation looks good, and the server can "execute" it. Meaning, the server can continue its process and actually fetch the data. The server walks down the AST.
For each field in the operation, the server invokes that field's resolver function—also called a datafetcher method in DGS. This method's mission is to "resolve" its field by populating it with the correct data from the correct source, such as a database or a REST API. These data sources don't necessarily need to live within the GraphQL server; they can be hosted externally.
In this way, GraphQL is a powerful bridge to REST (and other data sources!) that ties all of your app's data together. The GraphQL API acts as the layer on top of them, providing a single interface through which multiple datasources can be queried simultaneously.
As all of the operation's fields are resolved, the data is assembled into a nicely ordered JSON object with the exact same shape as the query.
The server assigns the object to the HTTP response body's
data key, and it's time for the return trip, back to our app.
Back to client-land
Our client receives the response with exactly the data it needs, passes that data to the right components to render them, and voilà, our data is brought to life in a UI.
Now that we have a birds-eye view of the full journey from client, to server, and back, we'll take some time to zoom into the the document that outlines all of our server's data capabilities: the GraphQL schema.
The GraphQL schema
The GraphQL server is where all the magic happens, but the schema tells us what's actually on the menu.
The GraphQL schema is a collection of types and fields that make up the comprehensive picture of everything we can do with the data in a GraphQL server. No actual data lives here; just the basic skeleton of the shapes that the live data will conform to. (Think of a blueprint!)
The schema has its own language called schema definition language, or SDL. We'll take a closer look at SDL syntax, and how to build the types and fields in our schema, in the next lesson.
Schema entry points
A GraphQL operation (the thing that the client sends to the GraphQL server) can either be a query, a mutation, or a subscription. A query reads data, a mutation changes data and a subscription listens for live, streaming data.
All three operations map to a corresponding type in the schema:
Query is like our front door to a GraphQL server. It defines a number of fields, each of which represents a path we can "follow" to get some data from our GraphQL server. Each field has its own name, and specifies the kind of data it returns. This makes it really easy to pick and choose different fields, and get all the data we want at once!
We can think of the fields within the
Query type as the list of things we can ask for from our GraphQL API. Similarly, the
Mutation type is the list of things we can do with our GraphQL API, as we'll see in a later lesson.
To build our GraphQL server, we'll use a "schema-first" design. That means we'll implement the project based on exactly which data our downstream consumers (like client applications running on mobile and desktop) will need. Schema-first design typically involves three major steps:
- Defining the schema: We identify which data our feature requires, and then we structure our schema to provide that data as intuitively as possible.
- Backend implementation: We build out our GraphQL API using DGS and fetch the required data from whichever data sources contain it. We'll start with hardcoded mocked data to learn the concepts, then hook our server up to a live REST data source.
- Consuming data: Clients are able to consume data from our GraphQL API.
One of the benefits of schema-first design is that it reduces total development time by allowing frontend and backend teams to work in parallel. The frontend team can start working with mocked data as soon as the schema is defined, while the backend team develops the API based on that same schema. This isn't the only way to design a GraphQL API, but we believe it's an efficient one, so we'll use it throughout this course.
Resolving schema fields with datafetchers
As we mentioned in the Journey of a GraphQL Query, for every type and field in the GraphQL schema, we can define a datafetcher method. A datafetcher retrieves the data for a specific field. These methods have access to various data sources: databases, REST APIs, even text files or JSON!
Datafetchers let us define the precise logic needed to retrieve data for a field, but we don't necessarily need to define a datafetcher by hand for EVERY field in our schema. We'll see how and when to define datafetcher functions in an upcoming lesson.
Drag items from this box to the blanks above
- There are three types of GraphQL operations: queries, mutations and subscriptions. A query reads data, a mutation changes data and a subscription listens for live, streaming data.
- The GraphQL schema is a collection of types and fields that make up the comprehensive picture of everything we can do with the data in a GraphQL server. It is written in schema definition language (SDL).
- A datafetcher method retrieves the data for a specific field in our schema. These functions have access to various data sources: databases, REST APIs, even text files or JSON. These data sources don't need to live within the GraphQL server.
This course is all about building a GraphQL server, so let's get into it! Grab a warm drink and get ready, it's time to dive into SDL.
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.