GraphQL Basics - Part 5: GraphQL Queries in Apollo Client
Tags: tutorial, graphql, react, apollo
Published: 2019-04-30 18:44:05

## GraphQL Queries
To get started with GraphQL queries we are going to first take a look at what a GraphQL query looks like, then we are going to see what writing a query looks like in Apollo on the front end.

If you've been following along with this tutorial, we have the following data model so far:
```javascript
type User {
  id: ID! @unique
  name: String!
}

type Item {
  itemId: ID! @unique
  name: String!
  cost: Int!
  shortDescription: String
  longDescription: String
}
```

Using GraphQL we can write a query for a specific user the following way:

```javascript
{
  query GET_USER_QUERY {
    user {
      id
      name
    }
  }
}
```
Here what each level has going on:
- `query GET_USER`: This establishes we are writing a query, and we give it the name GET_USER_QUERY. I just like to add 'query' or 'mutation' in the names for clarity sake.
- `user`: This is the specific query. It's also what our Apollo Server is going to look for in the **Resolvers**. Basically, we are telling the graphQL server to run the "user" resolver, which is similar to making a request from website.com/user in a REST API.
- `id, name`: Finally, inside of `user`, we state what we want to be returned, which is both the id and the name of the user. (Although, we could just ask for one of them if we wanted)

## REST API and GraphQL Compared
If you are coming from the land of a REST API, this is a little different. Basically, with a REST API, you end up hitting a certain URL endpoint, such as *somesite.com/user* and passing a query or params to the URL. You could use an express server to take those query params and use them in whatever logic to talk to the database and return data to you. (Super brief explanation obviously, I'm assuming you have some familiarity)

In a REST API, you have endpoints that you hit for certain requests/posts. An example would be _website.com/users_ to get a list of users or going to _website.com/posts_ for a full list of posts. You need an endpoint for all the different requests.

**With GraphQL your server is set up to accept all requests the same way, but similar to how a REST API has different endpoints where the logic for the requests goes, a GraphQL server has different *RESOLVERS* that tell each GraphQL how to be handled.**

![Mind Blown](https://media.giphy.com/media/xT0xeJpnrWC4XWblEk/giphy.gif)

## Writing the GraphQL Query from Frontend
Again, if you've been following along in the series, when we set up our graphQL server initially we were able to run queries against the sandbox endpoint (localhost:4000 on our project). That's great but, we need to be able to run the queries from our application, here's how we could do that!

- **Adding Users to Prisma DB**
First thing's first, we need to add a few users to our database in order to have something to query. We could do this programmatically, but I think that queries are easier to start within GraphQL, Prisma, and Apollo so what I did was just go into my Prisma DB, and add some users directly from the Prisma Admin.
![Prisma Admin Console](https://thepracticaldev.s3.amazonaws.com/i/sux4a42xm110otqez7rt.JPG)
Go to your Users in the admin console, and there is a + button (I highlighted it in yellow in the photo above) where you can just click to add users directly.

- **Add graphql-tag**
We need to add the package [graphql-tag](https://github.com/apollographql/graphql-tag) to our project. This lets us use template literals to parse the GraphQL language into out Apollo Queries. Simply `npm i graphql-tag`!

- **Make a Users Component**
Ok! So to write a query, we first need a component. We first need to create a file named _Users.js_ in our projects frontend/components directory. Inside we need to require a few things (in addition to the normal react stuff dependencies).
  - graphql-tag: For wrapping out GraphQL queries.
  - Query: The Query render prop from the react-apollo library.
We should have a basic start like below:
```javascript
  import React, { Component } from 'react';
  import gql from 'graphql-tag';
  import { Query } from 'react-apollo';
  
  
  class Users extends Component {
    render() {
      return (
        <p>I'm the user component.</p>
      );
    }
  }
  
  export default Users;
  ```
- **Add GraphQL Query to the User Component**
Next, we need to add the actual query. To get a better idea of the flow of writing a query from scratch, we are going to be making a query to get ALL users. To do this we use the gql tag and create a variable that holds the query in the gql tag.
```javascript
const GET_USERS_QUERY = gql`
  query GET_USERS_QUERY {
    users {
      id
      name
    }
  }
`;
```
- **Using the Query Component in Apollo Client**
To run our query, we use the Query component from Apollo Client. This is essentially a render prop that accepts our query as a prop, and behind the science runs the query against the database and returns data for us to work with!

To start off making sure everything is working, within the class we can put our <Query> component, passing the query as a prop, and within that, we have a single function that returns "data".
```javascript
class Users extends Component {
  render() {
    return (
      <Query query={GET_USERS_QUERY}>
        {(data) => {
          console.log(data)
          return <p>check log</p>
        }}
      </Query>
    );
  }
}
```
You can see how our function accepts data that get returned from the query, and currenlty we are simply returning a paragraph tag that say "check log" because we are logging the data to the console.

- **Make a User Page**
To see anything we need to make a new page that we can navigate to in our application.  In the frontend/pages directory, I made a new file named *users.js* and put the following:
```javascript
import React from 'react';
import Users from '../components/User';

const users = () => {
  return (
    <Users />
  );
};

export default users;
```
Because we are using Next.js, making a new component in the /pages directory will create the *users* route and that's where we put out Users component.

Now we should be able to go to **localhost:3000/users**, and see our data in the logs!

- **OOPS.  Fixing Errors**
Ok, if you have been following along 100% you now see errors. Full disclosure, I didn't plan this all out ahead of time and one problem I realized along the way is when setting up our servers, there are some CORS problems due to our frontend and backend being from different locations.

This can all be fixed by changing our _backend/index.js_ to look like this:
```javascript
const express = require('express');
const { Prisma } = require('prisma-binding');
const { ApolloServer } = require('apollo-server-express');
const { importSchema } = require('graphql-import');
const cors = require('cors');

const typeDefs = importSchema('./src/schema.graphql');
const Query = require('./src/Query');
const Mutation = require('./src/Mutation');

const db = new Prisma({
  typeDefs: './generated/prisma.graphql',
  endpoint: 'https://us1.prisma.sh/prisma-tutorial/prisma-graphql-tutorial/dev',
  secret: 'currentlyDrinkingPhilzCoffee'
});

const server = new ApolloServer({
  typeDefs,
  resolvers: {
    Mutation,
    Query
  },
  context: ({ req }) => ({
    ...req,
    db
  })
})

const app = express();

var corsOptions = {
  origin: 'http://localhost:3000',
  credentials: true // includes headers for the requests to backend
}

app.use(cors(corsOptions));

server.applyMiddleware({
  app,
  path: '/',
  cors: false // disbles default apollo-server cors and uses the express middleware cors in-lieu. 
})

app.listen({ port: 4000}, () => 
  console.log(`🚀 Server ready at localhost:4000`)
);
```
This is pretty similar to what we had before with one major adjustment. (Hopefully, the reasoning will be another post later on...)  Apollo Server actually handles CORS by default, and this becomes a problem if your frontend and backend are hosted in different places. Essentially what I've done here is this:
  - Changed const `{ ApolloServer } = require('apollo-server')` to `require('apollo-server-express')`
  - Created an express app
  - Added the cors middleware and passed it more specific options for out application, including the origin for frontend requests.
  - Applied the express middlewares to our express server, and set the Apollo Server cors to FALSE, meaning that the Apollo cors is disabled, and we are going to be using the cors middleware.

If all goes well, there should be NO http-header errors anymore! *But we still don't get any data returned, why is that?* Well, we created a query for `users` but we didn't give our Apollo server any **resolvers** to deal with the query. So far we only have a single query for an individual user.  The final step should be making a resolver for actually fetching all users.

- **Users Resolver**
This is pretty simple actually.  First, go to backend/src/schema.graphql and add a `users` query to our graphql schema. The Query type should look like this after adding the users:
```javascript
type Query {
  user(id: ID!): User
  users: [User]
}
```
So, we added a users query, and that's going to return an array of User objects.

Next, we need to write the logic for the Query, so we head to backend/src/Query.js and create a users query after the user query we already had.
```javascript
const Query = {
  user(parent, args, context, info) {
    if (!context.request.userId) {
      return null;
    }
    return context.db.query.user({
      where: { id: context.request.userId }
    }, info);
  },
  users(parent, args, context, info) {
    return context.db.query.users();
  }
};
```
This is a pretty straightforward query due to the fact we are asking for ALL users. We are just accessing the Prisma users() method, made available to us because we passed it into the context object way back when the server was made. So we are accessing the context, then out Prisma database (db), then we are accessing the prisma queries, and calling users() with no additional options. (You can pass users() more options, but we just want all users).

## Query Done!
At this point, (errors fixed and all) you should be able to go to *localhost:3000/users* and see logged to the console a data object with all of the users somewhere.  I have what I see below.
![Output](https://thepracticaldev.s3.amazonaws.com/i/ys1bwdcztsyrjsqjnndm.JPG)
You can see in the object that's returned, we actually have the users nested under data.users.

We have the data! But we can clean it up a little.
```javascript
<Query query={GET_USERS_QUERY}>
        {({data: {users} }) => {
          return (
            users.map(user => {
              return <p key={user.id}>{user.name}</p>
            })
          )
        }}
      </Query>
```
Because we know that data we want is within "data" in the object, we can restructure that, and then further destructure the users within data.  This lets us just access the array of users using "users."  Within the return of the Query component, we can map through the array of users, returning a <p> tag with a "key" set to their id (React want's unique keys) and return the users name within the tag. So, if you had 4 users, you would just get a list of them all output to the DOM.  Yay!

## Recap
To recap, making a a query involves the following core steps:
  1. **Writing the query**.
  2. **Adding the query** to your GraphQL schema.
  3. **Creating a resolver** to handle the query coming from the client.

Hopefully, this is a good intro to basic queries in Apollo and implementing them with our Prisma methods in the resolvers.  Next step, mutations!