GraphQL

with Apollo

Before we continue...

Spaces or Tabs?

What is GraphQL?

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.

What is Apollo?

The flexible, production ready GraphQL client for React and native apps.

Queries, caching, mutations, optimistic UI, subscriptions, pagination, server-side rendering, prefetching, and more.

Queries and Mutations

Get human with id of 1000 which includes name and height in feet.

Schema

type Author {
  id: Int! # the ! means that every author object _must_ have an id
  firstName: String
  lastName: String
  posts: [Post] # the list of Posts by this author
}

type Post {
  id: Int!
  title: String
  author: Author
  votes: Int
}

# the schema allows the following query:
type Query {
  posts: [Post]
}

Angular.js Demo

Queries

Apollo makes fetching the exact data you need for your component easy and allows you to put your queries exactly where you need them.

import { Component, OnInit } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

@Component({
  selector: 'post-list',
  template: `
    <div *ngIf="loading">Loading</div>
    <ul *ngIf="!loading">
      <li *ngFor="let post of posts">
        {{post.title}} by 
        {{post.author.firstName}} {{post.author.lastName}}
        ({{post.votes}} votes)
      </li>
    </ul>
  `
})
class PostListComponent implements OnInit {
  loading: boolean;
  posts: any[];

  constructor(private apollo: Apollo) {}

  ngOnInit() {
    this.apollo.watchQuery({
      query: gql`
        query allPosts {
          posts {
            id
            title
            votes
            author {
              id
              firstName
              lastName
            }
          }
        }
      `
    }).subscribe(({ loading, data }) => {
      this.loading = loading;
      this.posts = data.posts;
    });
  }
}
import { Component, Input } from '@angular/core';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';

@Component({
  selector: 'post-upvoter',
  template: `
    <button (click)="upvote(postId)>
      Upvote
    </button>
  `
})
class PostUpvoterComponent {
  @Input() postId: number;

  constructor(private apollo: Apollo) {}

  upvote(postId: number) {
    this.apollo.mutate({
      mutation: gql`
        mutation upvotePost($postId: Int!) {
          upvotePost(postId: $postId) {
            id
            votes
          }
        }
      `,
      variables: {
        postId
      }
    });
  }

}

React.js Demo

import React from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

// The data prop, which is provided by the wrapper below contains,
// a `loading` key while the query is in flight and posts when it is ready
function PostList({ data: { loading, posts } }) {
  if (loading) {
    return <div>Loading</div>;
  } else {
    return (
      <ul>
        {posts.map(post =>
          <li key={post.id}>
            {post.title} by {' '}
            {post.author.firstName} {post.author.lastName} {' '}
            ({post.votes} votes)
          </li>
        )}
      </ul>
    );
  }
}

Queries

// The `graphql` wrapper executes a GraphQL query and makes the results
// available on the `data` prop of the wrapped component (PostList here)
export default graphql(gql`
  query allPosts {
    posts {
      id
      title
      votes
      author {
        id
        firstName
        lastName
      }
    }
  }
`)(PostList);

Queries (cont.)

import React from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';

// A mutation is made available on a callback called `mutate`
// Other props of the wrapping component are passed through.
function PostUpvoter({ mutate, postId }) {
  return (
    <button onClick={() => mutate({ variables: { postId }})}>
      Upvote
    </button>
  )
}

// You can also use `graphql` for GraphQL mutations
export default graphql(gql`
  mutation upvotePost($postId: Int!) {
    upvotePost(postId: $postId) {
      id
      votes
    }
  }
`)(PostUpvoter);

Mutations

GraphQL

By James Brinkerhoff

GraphQL

  • 538