Set up a GraphQL client with Apollo
Apollo gives a neat abstraction layer and an interface to your GraphQL server. You don't need to worry about constructing your queries with request body, headers and options, that you might have done with Fetch.fetch
. You can directly write queries and mutations in GraphQL and they will automatically be sent to your server via your apollo client instance.
Installation
Let's get started by installing apollo client & peer graphql dependencies:
$ npm install --save apollo-client react-apollo reason-apollo apollo-cache-inmemory apollo-link-http graphql graphql-tag
You also need to add a helper package called graphql_ppx
to the dev dependencies to handle GraphQL query and mutation types elegantly.
npm install --save-dev graphql_ppx
Also, add reason-apollo
and graphql_ppx
to the bs-dependencies
and ppx_flags
respectively in your bsconfig.json
.
{"bs-dependencies": [...,"reason-apollo"],"ppx-flags": ["graphql_ppx/ppx"]}
Finally, you need a graphql_schema.json
in the root of your project so that the GraphQL queries and mutations are type checked against it. To get graphql_schema.json
,
- Go to https://hasura.io/learn/graphql/graphiql and login
- Copy the JWT from headers:
- Install Apollo CLI globally:
npm install -g apollo
- Run this command from the root of your project:
apollo schema:download --endpoint=https://hasura.io/learn/graphql --header "Authorization: Bearer <JWT>"
- Rename schema.json to graphql_schema.json
Setup
Create a file called src/ApolloClient.re
and create an instance of Apollo Client in it as follows:
// in memory cache for caching GraphQL datalet cache = ApolloInMemoryCache.createInMemoryCache();// apollo link instance as a network interface for apollo client// apollo link also has to be configured with headers// we get token from local storage and configure apollo link headers with itlet headers = switch(Util.getTokenFromStorage()) {| None => Json.Encode.object_([])| Some(token) => {Js.log(token);Json.Encode.object_([("Authorization", Json.Encode.string("Bearer " ++ token))])}};let link = ApolloLinks.createHttpLink(~uri="https://hasura.io/learn/graphql",~headers=headers,());// apollo client instancelet instance = ReasonApollo.createApolloClient(~link, ~cache, ());[@bs.module] external gql: ReasonApolloTypes.gql = "graphql-tag";
Let's try to understand what is happening here.
We are creating an HttpLink
to connect ApolloClient with the GraphQL server. As you know already, our GraphQL server is running at https://hasura.io/learn/graphql
. We are also configuring the headers with the JWT token from the local storage.
At the end, we instantiate ApolloClient by passing in our HttpLink
and a new instance of InMemoryCache
(recommended caching solution). This instance can be used anywhere in the application as `.
We also write a custom binding for gql
so that we can fire GraphQL Queries manually without the JSX components. (more on this later)
Finally, we have to use this instance in src/App.re
to provide the child application with Apollo Client so that its features can be leveraged throughout the application.
[@react.component]let make = () => {- <div>+ <ReasonApollo.Provider client=ApolloClient.instance><Navbar /><div className="container-fluid p-left-right-0"><div className="col-xs-12 col-md-9 p-left-right-0"><div className="col-xs-12 col-md-6 sliderMenu p-30"><TodoPrivateWrapper /></div><div className="col-xs-12 col-md-6 sliderMenu p-30 bg-gray border-right"><TodoPublicWrapper /></div></div><div className="col-xs-12 col-md-3 p-left-right-0"><div className="col-xs-12 col-md-12 sliderMenu p-30 bg-gray"><OnlineUsersWrapper /></div></div></div>- </div>+ </ReasonApollo.Provider>}
- Build apps and APIs 10x faster
- Built-in authorization and caching
- 8x more performant than hand-rolled APIs