Part 1 — Front end: Use Apollo declaratively to request and mock data

GraphQL is a new API definition and query language that has the potential to become the new REST. It makes it easy for UI components to get data declaratively without worrying about back-end implementation details. GraphQL is a powerful abstraction that speeds up application development and makes code easier to maintain.

However, despite the benefits of using GraphQL, getting started may not be easy. That’s why I’ve written this series of tutorials that take you step by step through writing a full-stack React application that includes GraphQL and Apollo Client. This series will walk you through building a complete instant messaging application using GraphQL:

  • Part 1 (this article) : Set up a simple client

  • Part 2: Setting up a simple server
  • Part 3: Writing changes and keeping clients in sync
  • Part 4: Active UI and client Store updates
  • Part 5: Input types and custom cache parsers
  • Part 6: Server side subscription
  • Part 7: Client GraphQL subscription

This tutorial — the first in a series — is about getting started with GraphQL on the front end. It only takes about 20-30 minutes and you end up with a very simple React UI that uses GraphQL to load data and looks like this:

A simple React UI that uses GraphQL to load data

Let’s get started!

1. Environment construction

Note: To complete this tutorial, you need to have Node, NPM, and Git installed on your machine and know React.

We will use create-react-app in this tutorial, so install:

> npm install -g create-react-app
Copy the code

We also need to clone the tutorial’s codebase from GitHub, which contains the CSS and images we’ll use later.

> git clone https://github.com/apollographql/graphql-tutorial.git
> cd graphql-tutorial
Copy the code

Next, we use create-react-app to create our React application.

> create-react-app client
> cd client
Copy the code

To make sure it works, we start the server:

> npm start
Copy the code

If all is well, you should now see something like this in your browser:

2. Write the first component

Since we are building an application using Apollo, we are building an application from… / resources Copy logo.svg and app.css to modify the logo and CSS.

> cd src > cp .. /.. /resources/* .Copy the code

To simplify the initial tutorial, we’ll just build a simple list view today. Let’s modify the code in app.js:

  1. Change Welcome to React to Welcome to Apollo. Apollo is the name of the GraphQL client that we will use throughout this tutorial series.

  2. Delete “To get started..” And replace it with the pure React component, which will render a section withTwo list itemsUnordered lists of “Channel 1” and “Channel 2” (yes, you guessed it, we’re building a communication app!). . Let’s name the list componentChannelsList.

Your app.js should now look like this:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
Copy the code
const ChannelsList = () =>
     (<ul>
       <li>Channel 1</li>
       <li>Channel 2</li>
     </ul>);
Copy the code
class App extends Component { render() { return ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Welcome to Apollo</h2> </div> <ChannelsList /> </div> ); }}Copy the code
export default App;
Copy the code

Create-react-app sets up hot loading for you, so once you save the file, the browser window your app is in will update to reflect the change:

If it looks like this, your setup is correct.

3. Write your GraphQL Schema

Now that we have a simple application running, it’s time to write the GraphQL type definition for it. Schema specifies which object types exist in our application and which fields they have. In addition, it specifies the entry to our API. Let’s create a new file called schema.js:

export const typeDefs = `
Copy the code
type Channel { id: ID! # "!" Mandatory name: String}Copy the code
This type specifies the entry point to our API. In this case, only one -- "Channels" -- returns the list of channels. Type Query {channels: [Channel] # "[]" means this is a list of channels} ';Copy the code

With this schema, we can write a simple query in the next section to get the data for our ChannelList component. Here is our query:

query ChannelsListQuery {
  channels {
    id
    name
  }
}
Copy the code

4. Connect your component to the GraphQL query

Ok, now that we have the schema and query, we just need to connect our components using the Apollo Client! To install Apollo Client and some auxiliary packages, we need to add GraphQL to our application:

> npm i -S react-apollo
Copy the code

React – Apollo is an Apollo Client integration with React that lets you decorate components with a higher-order component called GraphQL, which effortlessly imports your GraphQL data into the component. React Apollo also provides ApolloClient, which is Apollo’s core and handles all data fetching, caching, and active updates (which we’ll discuss in another tutorial).

Now let’s add some imports at the top of app.js and create an instance of Apollo Client:

import {
  ApolloClient,
  gql,
  graphql,
  ApolloProvider,
} from 'react-apollo';
Copy the code
const client = new ApolloClient();
Copy the code

Next, we decorate the original ChannelsList with the GraphQL high-level component that accepts the query and passes the data to our component:

const channelsListQuery = gql`
   query ChannelsListQuery {
     channels {
       id
       name
     }
   }
 `;
Copy the code
const ChannelsListWithData = graphql(channelsListQuery)(ChannelsList);
Copy the code

When our ChannelsList component uses graphQL HOC wrapping, we receive a prop named Data that contains a channel when it is available and displays an error when there is an error. Data also contains a loading property that is true when the Apollo Client is waiting for data to be loaded.

Next modify our ChannelsList component to ensure that the user knows if the component is loading or if there is an error:

const ChannelsList = ({ data: {loading, error, channels }}) => { if (loading) { return <p>Loading ... </p>; } if (error) { return <p>{error.message}</p>; }Copy the code
   return <ul>
     { channels.map( ch => <li key={ch.id}>{ch.name}</li> ) }
   </ul>;
 };
Copy the code

Finally, we replace ChannelsList in the render function of our App with ChannelsListWithData. To enable the component we just created to use an instance of the Apollo Client, we wrap the top-level application component with ApolloProvider, which puts an instance of the Apollo Client on the UI.

Your App component should now look like this:

class App extends Component { render() { return ( <ApolloProvider client={client}> <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Welcome to Apollo</h2> </div> <ChannelsListWithData /> </div> </ApolloProvider> ); }}Copy the code

Ok, we’re almost done! If you try to run it now, you should see the following error:

It worked! Well, at least in part.

What’s going on here? Although we connected all the components correctly, we haven’t written a server yet, so of course there’s no data to fetch or display! If you do not specify a URL for the GraphQL endpoint, Apollo Client will assume that it is running in the same field as/GraphQL. So we need to create a web interface with a custom URL.

However, since this tutorial isn’t about writing a server, we’ll use GraphQL code as a document feature to automatically mock out the type definitions we wrote earlier. To do this, we just need to stop the server, install some other packages, and then restart it:

npm i -S graphql-tools apollo-test-utils graphql
Copy the code

We will use these packages to create a mock network interface for Apollo Client based on the schema we wrote earlier. Add the following imports and definitions to the top of app.js:

import { 
  makeExecutableSchema,
  addMockFunctionsToSchema
} from 'graphql-tools';
 import { mockNetworkInterfaceWithSchema } from 'apollo-test-utils';
 import { typeDefs } from './schema';
Copy the code
const schema = makeExecutableSchema({ typeDefs });
addMockFunctionsToSchema({ schema });
Copy the code
const mockNetworkInterface = mockNetworkInterfaceWithSchema({ schema });
Copy the code

Now you just need to pass the mockNetworkInterface to the Apollo Client constructor:

const client = new ApolloClient({
   networkInterface: mockNetworkInterface,
 });
Copy the code

That’s it! You’ve done it! Your screen should now look like this:

We did it, our first React + GraphQL app using Apollo!

Note: “Hello World” is just the default mock text for the string. If you want to customize cool mocks, check out this post I wrote earlier.

If something doesn’t work, and you’re not sure why, you can compare it to this file to find code differences. Alternatively, you can check the code by looking at the T1-end Git branch.


Congratulations, you have officially completed the first part of the tutorial! It may not feel like much, but you’ve actually done a lot of work: You’ve written a GraphQL Schema, generated mock data from it, and connected the GraphQL query to the React component. In the rest of this tutorial, you will learn the basics of building a real communication application. In Part 2, we’ll write a simple server and connect it to our application!