Skip to content

Instantly share code, notes, and snippets.

@maapteh
Created November 28, 2018 16:08
Show Gist options
  • Save maapteh/3c765614bc2e96ccf77cc97ec22e84e4 to your computer and use it in GitHub Desktop.
Save maapteh/3c765614bc2e96ccf77cc97ec22e84e4 to your computer and use it in GitHub Desktop.
apollo client with batched http and option to get out of batch by setting important on context
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { ApolloLink, split } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { HttpLink } from 'apollo-link-http';
import { BatchHttpLink } from 'apollo-link-batch-http';
// add fragments from apollo endpoint
import { fragmentMatcher } from './fragment-matcher';
// TODO: link http://gateway:8080/graphql and https://foo.bar/graphql for each environment
const uri = "https://foo.bar/graphql";
// link to use if batching (default)
// also adds a `batch: true` header to the request to prove it's a different link
const batchHttpLink = new BatchHttpLink({ uri, headers: { batch: 'true ' } });
// link to use if not batching
const httpLink = new HttpLink({ uri });
export function createClient(): ApolloClient<NormalizedCacheObject> {
// Create the cache first, which we'll share across Apollo tooling.
// This is an in-memory cache. Since we'll be calling `createClient` on
// universally, the cache will survive until the HTTP request is
// responded to (on the server) or for the whole of the user's visit (in
// the browser)
const cache = new InMemoryCache({
fragmentMatcher,
cacheRedirects: {
Query: {
// Here we can map the data we get in list view with the one for detail view
// see: https://www.apollographql.com/docs/react/features/performance.html
},
}
}) as any;
// If we're in the browser, we'd have received initial state from the
// server. Restore it, so the client app can continue with the same data.
if (process.env.BROWSER) {
cache.restore((window as any).__APOLLO_STATE__);
}
// Return a new Apollo Client back, with the cache we've just created,
// and an array of 'links' (Apollo parlance for GraphQL middleware)
// to tell Apollo how to handle GraphQL requests
return new ApolloClient({
cache,
connectToDevTools: !!process.env.BROWSER,
ssrMode: !process.env.BROWSER, // On the server, enable SSR mode which disables forceFetch on the server (so queries are only run once)
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) console.log(`[Network error]: ${networkError}`);
}),
split(
operation => operation.getContext().important === true,
httpLink, // if the test is true -- debatch
batchHttpLink // otherwise, batching is fine
),
]),
});
}
@maapteh
Copy link
Author

maapteh commented Nov 28, 2018

when not using ssr false it gets it SSR, when not setting important on context it will get batched.

<Query query={GET_PRODUCT_BY_ID} variables={{ id: 61130}} ssr={false} context={{ important: true }}>
    {({ loading, error, data }) => {
        if (loading) return null;
        return (
            <Product product={data.getProductById} />
        );
    }}
</Query>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment