Simplest Network Layer

The simplest network layer would get the request and send it to a GraphQL server to resolve and return the data to Relay environment.

The body of our request has the GraphQL query and the variables.

If it is a mutation it throw an error when there is data.errors.

We return the GraphQL response to update the Relay Environment (store where relay keep the data).

Network that Handle Uploadables

If you wanna send files to your GraphQL Server, you need to change your request body to use FormData.

Network that Caches Requests

Built on top of the other 2 implementations, we use RelayQueryResponseCache to query GraphQL requests based on query and variables. Every time a mutation is done, we should invalidate all cache as we are not sure how this affect all cached queries responses.

Network using Observable

Relay provides a limited implementation of ESObservables. I recommend reading A General Theory of Reactivity to understand why we need to use Observable instead of promises in some situations. While a promise is one value in a time space, an observable is a stream of values in a time space.

Instead of return a promise that will resolve a single GraphQL response. We return an Observable that could fulfill many responses before it finishes.

This is used on GraphQL Living Queries, as you are going to resolve the same query more than once.

Deferrable Queries Network

A common case for deferrable queries is to lazy load fragments, like let's load Post content first and then load all comments of this post after the post is loaded.

Without deferrable queries you could simulate this using @include Relay Modern directive and a refetch container, when the component mounts it will change the variable used on @include to true and get the rest of the data.

The problem with above approach is that you need to wait the component to mount before start the next request, this will be more a big deal when Async React start working.

The deferrable query will start as soon as the previous query has finished.

In the fragment above, it will first get title and commentsCount data from Post, and after it will get the data for CommentsList_post fragment.

Here is the implementation of an execute function to handle a batched request:

Our execute function now can handle 2 types of requests: a Request that is a single GraphQL query; and a BatchRequest that could have many queries with interrelated data among them.

So how does a batchRequestQuery looks like:

getDeferrableVariables function will get variables from result data from other requests.

batchRequestQuery function will execute each of the requests, and will sink.next() as soon as it has the GraphQL server response data. It will only close the Observable stream when all requests has been fullfiled.