Category Archives: Apollo

Apollo GraphQL client

Based upon our previous implementation(s) of a server it’s now time to write some client code.

  • yarn add apollo-client
  • yarn add apollo-cache-inmemory
  • yarn add apollo-link-http
  • yarn add graphql-tag
  • yarn add isomorphic-fetch
  • yarn add -D @types/isomorphic-fetch

Now let’s create a simple script entry (this extends the previous post’s scripts section)

"scripts": {
  "build": "tsc",
  "client": "node client.js"
}

Now let’s create the file client.ts which should look like this

import ApolloClient from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import gql from 'graphql-tag';
import fetch from 'isomorphic-fetch';

const cache = new InMemoryCache();
const link = new HttpLink({
  uri: 'http://localhost:4000/',
  fetch: fetch
})

const client = new ApolloClient({
  cache,
  link,
});

client.query({
  query: gql`
    {
    users {
      firstName
      lastName
    }
  }`
  })
  .then((response: any) => console.log(response.data.users));

The response.data.users should now output the array of User objects.

Here’s an example of a mutation

client.mutate({
  mutation: gql`
    mutation {
      create(user: {
        firstName: "Miner",
        lastName: "FortyNiner"
      }) {
        firstName
        lastName
      }
    }
  `
}).then((response: any) => console.log(response.data.create));

Note: I had lots of issues around the fetch code, with errors such as Invariant Violation:
fetch is not found globally and no fetcher passed, to fix pass a fetch for your environment like
https://www.npmjs.com/package/node-fetch.
. The addition of the isomorphic-fetch solved this problem.

Writing our first Apollo GraphQL server

In the previous posts we’ve seen how to build an express based server and eventually add GraphQL to it.

graphql-express is not the only option for implementing GraphQL servers, let’s now look at Apollo – I cannot say whether one library is better than the other as I’ve not used them enough to comment although.

Let’s go through the process of creating a new project for this, so carry out the following steps

  • Create a folder for your project
  • cd to that folder
  • Run yarn init -y
  • Run tsc –init
  • Add a folder named models and a file named user.ts (we’ll use the same model/data from the previous posts), here’s the code for this file
    export default class User {
      constructor(public firstName: string, public lastName: string) {
      }
    }
    
    export const stubData = [
      new User('Scooby', 'Doo'),
      new User('Fred', 'Jones'),
      new User('Velma', 'Dinkley'),
      new User('Daphne', 'Blake'),
      new User('Shaggy', 'Rogers'),
    ];
    

So that’s the basics in place for the support data and model, let’s now look at the specifics for Apollo.

We’re going to create a file for the resolvers named resolver.ts and here’s the code

import User, { stubData } from "./models/user";

export const resolvers = {
  Query: {
    users: () => stubData,
  },
  Mutation: {
    create: (parent: any, args: any): User => {
      const data = new User(args.user.firstName, args.user.lastName)
      stubData.push(data);
      return data;
    }
  }
}

As you can see, we specify the Query and Mutation separately and the code’s pretty much the same as the express-graphql implementation except in the create mutation parameters. In this case the parent will supply any parent nodes whilst the args supplies the parameters from the mutation call.

Now we’ll create the file server.ts which will have the (as I’m sure you guessed) the server code as well as the schema definition (Apollo names this typeDefs).

import { ApolloServer, gql } from "apollo-server";
import { resolvers } from "./resolvers";

const typeDefs = gql`
type User {
    firstName: String
    lastName: String
  }

  input UserInput {
    firstName: String
    lastName: String
  }

  type Mutation {
    create(user: UserInput): User
  }

  type Query {
    users: [User]
  }
`;

const server = new ApolloServer({ typeDefs, resolvers });

server.listen()
  .then(({ url }) => {
    console.log(`Server listening to ${url}`);
  });

Note that Apollo uses a template tag gql function to declare the GraphQL schema, which along with the resolves is passed into the ApolloServer, then we simply start the server.

If you now run yarn build followed by yarn run the server will run up with default port 4000. Navigating to http://localhost:4000/ will display the GraphQL playground.

So, as you can see, Apollo is very simple to set-up for use as a GraphQL server.