Love 💟 and rage 😠 can be so close together.
This is a series of posts how I felt while working on my first project with Apollo, GraphQL, and reactjs. Also, you will learn how to set it up!
I always have this love 💟 and passion 💪 for new shiny things. The same happened when I saw GraphQL for the first time. I want to learn this new shiny thing 🤩 ! It was a cloudy rainy 🌧 Saturday so I thought to my self it is the perfect time to start a new project.
The setup
I started with my old good friend create-react-app
.
npx create-react-app react-apollo
#or
yarn create react-app react-apollo
That's was easy. You have a react frontend. Now change the directory and start the frontend.
cd react-apollo
yarn start
#or
npm start
Let us add Apollo and GraphQL to the frontend.
After some searching on google, I found apollo-boost
.
The README.md
looked good to me so I installed it.
npm I apollo-boost graphql react-apollo -S
#or
yarn add apollo-boost graphql react-apollo
Okay, this looks nice. just a boost package the base GraphQL package and the react integration package. clean!
Creating the Apollo client
lets set it up aka let us create an Apollo client. So the README.md
suggested the following code.
import React from 'react';
import { render } from 'react-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
// Pass your GraphQL endpoint to uri
const client = new ApolloClient({ uri: 'https://nx9zvp49q7.lp.gql.zone/graphql' });
const ApolloApp = AppComponent => (
<ApolloProvider client={client}>
<AppComponent />
</ApolloProvider>
);
render(ApolloApp(App), document.getElementById('root'));
After reading through that code, I and eslint
saw three problems 🤔. App
is not imported and also render()
is rendering to the root. Okay, so no copy and paste here with create-react-app
and we don't have an endpoint for Apollo right now 😩. Google to the rescue again 🙏. Searching for open graphql endpoints
I found an endpoint for pokemon! Nice. the URI is https://graphql-pokemon.now.sh
.
Okay, problem one solved. Let's start to change our create-react-app
.
First, create a file src/apollo.jsx
with the following code.
import React from 'react';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
// Pass your GraphQL endpoint to uri
const client = new ApolloClient({ uri: 'https://graphql-pokemon.now.sh/' });
export default AppComponent => (
<ApolloProvider client={client}>
<AppComponent />
</ApolloProvider>
);
Now change your index.js file so it looks like this:
import { render } from 'react-dom';
import './index.css';
import ApolloApp from './apollo';
import App from './App';
import * as serviceWorker from './serviceWorker';
render(ApolloApp(App), document.getElementById('root'));
serviceWorker.unregister();
We imported ApolloApp
and wrapped the App
in ApolloApp
. Yeah, the naming is not the greatest. Save and check if everything is still working! See if the terminal and localhost:3000
is happy 😊.
Our first query
The pokemon GraphQL endpoint is very limited. We can only query by name or by id 😯.
Create a file src/PokemonByName.js
and add the following code.
import React from 'react';
import { gql } from 'apollo-boost';
import { Query } from 'react-apollo';
const GET_POKEMON = gql`
query pokemon($name: String!) {
pokemon(name: $name) {
id
number
name
}
}
`
export default ({ name }) => (
<Query query={GET_POKEMON} variables={{ name }}>
{({ loading, error, data }) => {
if (loading) return null;
if (error) return `Error!: ${error}`;
if(!!data.pokemon){
return (
<div>
{data.pokemon.name} {data.pokemon.number}
</div>
);
}
return (
<div>
{name} not Found
</div>
);
}}
</Query>
);
😵 Puh, that's a lot of code! We are creating a query named GET_POKEMON. gql
is a template language. $name
is a variable of the type String
and it is required. It is required because there is an !
. The Query will return an object with the internal id, the Pokedex number and the name of the pokemon. We are also creating a component where we actually send the GraphQL query. We pass the name of the pokemon as a prop. Then we don't render anything if it is still loading. We render an error if we get one and then we are checking if we actually found a pokemon. If yes then render the name and number and if not render a message that the pokemon with that name was not found.
Let's actually make it happen that we can see something on the screen!
so change the file src/app.js
. to the following.
import React, { Fragment } from 'react';
import PokemonByName from './PokemonByName';
import './App.css';
const App = () => (
<Fragment>
<PokemonByName name={'pikachu'} />
<PokemonByName name={'charmander'} />
<PokemonByName name={'bulbasaur'} />
</Fragment>
)
export default App;
We are importing our new component and then we are adding it three times to our App component. Now just save everything and have a look at your browser how it renders the pokemon on your screen! Beautiful 😍!
So now we know how to integrate a GraphQL endpoint into our app.
Next time we will try to create our own GraphQL endpoint! I wonder how is that will be (or not).
Thanks for reading!
Top comments (4)
Example link:
pokemon-apollo.netlify.com/
Ahh nice! did you open source that code ? :)
Yes, i did.
Github link
You can try visualizing your schema with app.graphqleditor.com/