GraphQL has been getting popular recently and is likely to replace the Rest API. In this tutorial, we will use Apollo Client to communicate with GitHub’s GraphQL API. We will integrate Apollo Client with ReactJS, but you can use it with several other client platforms as well.
This tutorial does not cover how to start a React project, but you can use create-react-app
to get started.
Once we have the react app ready to go, the next thing is to install the required modules.
Installing Modules
The following line installs all the required modules.
npm install apollo-client-preset react-apollo graphql-tag graphql --save
Now we can provide our component with a client.
Providing a Client to a Component
You can provide a client anywhere in your React component hierarchy. However, it is always a good practice to provide the component, wrapping your whole application, with the client.
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import { ApolloProvider } from 'react-apollo'; import { ApolloClient } from 'apollo-client'; import { HttpLink } from 'apollo-link-http'; import { InMemoryCache } from 'apollo-cache-inmemory'; const token = "YOUR_TOKEN"; const httpLink = { uri: 'https://api.github.com/graphql', headers: { authorization: `Bearer ${token}` } }; const client = new ApolloClient({ link: new HttpLink(httpLink), cache: new InMemoryCache() }); ReactDOM.render(, document.getElementById('root'));
Above you can see that we defined the uri
for GitHub and also used a specific token for headers
. You should be using your own token generated from GitHub. So don’t forget to replace it with YOUR_TOKEN
.
For this example, we defined the API token on the client side. However, you should not reveal your API token publicly. So it is always good to keep it on the server abstracted from the client side.
Notice that we have wrapped the
component with ApolloProvider
and used the client
variable we created for the client
prop.
GraphiQL Application
Before diving into the queries, I want to point out that there is a very handy tool called GraphiQL for testing your GraphQL queries. Before proceeding, make sure that you have downloaded it.
Once you open GraphiQL, you need to set the GraphQL Endpoint and HTTP Headers.
GraphQL Endpoint: https://api.github.com/graphql
Header Name: Authorization
Header Value: Bearer YOUR_TOKEN
Of course, you need to replace YOUR_TOKEN with your own token. Do not forget to include the Bearer in front of your token when defining the Header Value.
If you do not want to download an application, you can also use the online GraphQL API Explorer for GitHub.
GraphQL Queries
Unlike a REST API with several end-points, the GraphQL API has only one end-point, and you only fetch what is defined by your query.
The documentation of GitHub’s GraphQL API gives you more insight.
Also, the best part of the GraphiQL application is that it gives you access to documentation for queries right inside the application. You can see the sidebar on the right named Docs.
Let’s start with the simplest query:
query{ viewer{ login } }
This query returns you the login information of the viewer. In this case, the viewer is you since you used your own API token.
In this tutorial, I will not give detailed information on queries. You can always refer to the documentation and try queries on GraphQL tools to see if you are getting the correct data.
Let’s use the following query for the rest of the tutorial.
query($name: String!){ search(query: $name, last: 10, type: REPOSITORY) { edges { node { ... on Repository { id name description url } } } } }
This query searches for the last 10 repositories matching the specific input string, which we will define in our application.
It returns the id, name, description, and url for each result.
Using the GraphQL Query in a React Component
We need to import the two modules below to our React component to be able to define the query within the component and then pass the results to the component as props.
import gql from 'graphql-tag'; import { graphql } from 'react-apollo';
Here we assigned our query to a constant variable, but we haven’t defined the name
parameter yet.
const repoQuery = gql` query($name: String!){ search(query: $name, last: 10, type: REPOSITORY) { edges { node { ... on Repository { id name description url } } } } } `
Now we wrap our component with the graphql HOC (Higher Order Component) in order to define the query parameters, execute the query, and then pass the result as props to our component.
const AppWithData = graphql( repoQuery, { options: { variables: { name: "tuts" } } } )(App)
Below is the final version of our component.
import React, { Component } from 'react'; import gql from 'graphql-tag'; import { graphql } from 'react-apollo'; class App extends Component { render() { return (); } } const repoQuery = gql` query($name: String!){ search(query: $name, last: 10, type: REPOSITORY) { edges { node { ... on Repository { id name description url } } } } } ` const AppWithData = graphql( repoQuery, { options: { variables: { name: "tuts" } } } )(App) export default AppWithData;
Note that we do not export the actual App
component but the wrapped component, which is AppWithData
.
Check the Data in the Console
Let’s go ahead and add {console.log(this.props)}
to the render method of your component.
class App extends Component { render() { console.log(this.props) return (); } }
When you check the console of your browser, you will see there are two object logs.
Inside each object, you will see the data
property. This is provided to our component through the graphql
HOC.
Notice that the first log has the loading: true
property inside data
, and the second log has loading: false
and a new object named search
, which is exactly the data we wanted to get.
Display the Data
Let’s write some JSX to display the fetched data.
Since the search
object is not initially there, we cannot directly try to render it. Therefore, first we need to check if we fetched the data and the search
object is ready to be used.
In order to do that, we will simply use the loading
information provided inside the data
property.
If loading
is true
then we simply render the Loading text, otherwise the data itself.
class App extends Component { render() { return ({this.props.data.loading === true ? "Loading" : this.props.data.search.edges.map(data =>); } })}
- {data.node.name}
- {data.node.description}
I used the ?:
ternary operator for basic inline conditional expressions. If loading
is true
we display Loading, and if it is false, we use the map function to iterate through our data array to display the information inside the
- and
elements.
This is just a basic example. You can use a regular if-else statement and return different results for your render method.
You can check the Apollo-Client-with-React repository, clone it on your computer, and play around.
P.S. Don’t forget to replace the token
variable with your own API token for GitHub.
Conclusion
We covered how to get started with Apollo Client for React. We installed the required modules, set up the client, and then provided it to our component at the top of the component hierarchy. We learned how to test GraphQL queries quickly before implementing them in our actual application. Finally, we integrated the query into a React component and displayed the fetched data.
Powered by WPeMatico