Nikolas Burk
Written By
Nikolas Burk
Developer @ Prisma

Nikolas is a developer and head of content at Prisma. He is excited about GraphQL as a new API technology and has a passion for learning and sharing knowledge.

Getting Started

Since this is a frontend track, you’re not going to spend any time implementing the backend. Instead, you’ll use the server from the Node tutorial.

Once you created your React application, you’ll pull in the required code for the backend.

Note: The final project for this tutorial can be found on GitHub. You can always use it as a reference whenever you get lost throughout the course of the following chapters. Also note that each code block is annotated with a filename. These annotations directly link to the corresponding file on GitHub so you can clearly see where to put the code and what the end result will look like.

Frontend

Creating the app

First, you are going to create the React project! As mentioned in the beginning, you’ll use create-react-app for that.

This will create a new directory called hackernews-react-apollo that has all the basic configuration setup.

Make sure everything works by navigating into the directory and starting the app:

cd hackernews-react-apollo
yarn start

Note: This tutorial uses Yarn for dependency and project management. Find instructions for how you can install it here. If you prefer using npm, you can just run the equivalent commands.

This will open a browser and navigate to http://localhost:3000 where the app is running. If everything went well, you’ll see the following:

Great job! 👏

.../hackernews-react-apollo/src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './styles/index.css'
import App from './components/App'

Your project structure should now look as follows:

.
├── README.md
├── node_modules
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src
│   ├── App.test.js
│   ├── components
│   │   └── App.js
│   ├── index.js
│   ├── logo.svg
│   ├── registerServiceWorker.js
│   └── styles
│       ├── App.css
│       └── index.css
└── yarn.lock

Prepare styling

This tutorial is about the concepts of GraphQL and how you can use it from within a React application, so we want to spend the least time possible on styling. To reduce the usage of CSS in this project, you’ll use the Tachyons library which provides a number of CSS classes.

Since we still want to have a bit more custom styling here and there, we also prepared some styles for you that you need to include in the project.

Install Apollo Client

Here’s an overview of the packages you just installed:

  • apollo-boost offers some convenience by bundling several packages you need when working with Apollo Client:

    • apollo-client: Where all the magic happens
    • apollo-cache-inmemory: Our recommended cache
    • apollo-link-http: An Apollo Link for remote data fetching
    • apollo-link-error: An Apollo Link for error handling
    • apollo-link-state: An Apollo Link for local state management
    • graphql-tag: Exports the gql function for your queries & mutations
  • react-apollo contains the bindings to use Apollo Client with React.
  • graphql contains Facebook’s reference implementation of GraphQL - Apollo Client uses some of its functionality as well.

That’s it, you’re ready to write some code! 🚀

Configure ApolloClient

Apollo abstracts away all lower-level networking logic and provides a nice interface to the GraphQL server. In contrast to working with REST APIs, you don’t have to deal with constructing your own HTTP requests any more - instead you can simply write queries and mutations and send them using an ApolloClient instance.

The first thing you have to do when using Apollo is configure your ApolloClient instance. It needs to know the endpoint of your GraphQL API so it can deal with the network connections.

Note: The project that was generated by create-react-app uses semicolons and double quotes for strings. All the code that you’re going to add will use no semicolons and mostly single quotes. You’re also free to delete any existing semicolons and replace double with single quotes 🔥

Let’s try to understand what’s going on in that code snippet:

  1. You’re importing the required dependencies from the installed packages.
  2. Here you create the httpLink that will connect your ApolloClient instance with the GraphQL API, your GraphQL server will be running on http://localhost:4000.
  3. Now you instantiate ApolloClient by passing in the httpLink and a new instance of an InMemoryCache.
  4. Finally you render the root component of your React app. The App is wrapped with the higher-order component ApolloProvider that gets passed the client as a prop.

That’s it, you’re all set to start loading some data into your app! 😎 In the next section, you’re adding the server that will provide that data.

Backend

The overall architecture of your app looks as follows:

In the following sections, you’re going to configure all backend components:

  • API server (based on graphql-yoga)
  • Prisma
  • Database (you’ll use a free and hosted demo AWS Aurora database in Prisma Cloud)

Downloading the server code

As mentioned above, for the backend in this tutorial you’ll simply use the final project from the Node tutorial.

Note: If you are on Windows, you may want to install Git CLI to avoid potential problems with commands such as curl.

You now have a new directory called server inside your project that contains all the code you need for your backend.

Before you start the server, let’s quickly understand the main components:

  • prisma: This directory holds all the files that relate to your Prisma and database setup. Prisma is used as a replacement for a traditional ORM and is responsible for accessing the database (using the Prisma client).

    • prisma.yml is the root configuration file for Prisma.
    • datamodel.prisma defines your datamodel. Every model gets mapped to a table in the database.
  • src: This directory holds the source files for your GraphQL server.

    • schema.graphql contains your GraphQL schema.
    • resolvers contains the resolver functions for the operations defined in the GraphQL schema.
    • index.js is the entry point for your GraphQL server.

From the mentioned files, only the application schema defined in server/src/schema.graphql is relevant for you as a frontend developer. This file contains the GraphQL schema which defines all the operations (queries, mutations and subscriptions) you can send from your frontend app.

Here is what it looks like:

.../hackernews-react-apollo/server/src/schema.graphql
scalar DateTime

type Query {
  feed(filter: String, skip: Int, first: Int, orderBy: LinkOrderByInput): Feed!
}

enum LinkOrderByInput {
  description_ASC
  description_DESC
  url_ASC
  url_DESC
  createdAt_ASC
  createdAt_DESC
}

type Feed {
  links: [Link!]!
  count: Int!
}

type Mutation {
  post(url: String!, description: String!): Link!
  signup(email: String!, password: String!, name: String!): AuthPayload
  login(email: String!, password: String!): AuthPayload
  vote(linkId: ID!): Vote!
}

type Subscription {
  newLink: Link
  newVote: Vote
}

type AuthPayload {
  token: String
  user: User
}

type User {
  id: ID!
  name: String!
  email: String!
  links: [Link!]!
}

type Link {
  id: ID!
  createdAt: DateTime!
  description: String!
  url: String!
  postedBy: User
  votes: [Vote!]!
}

type Vote {
  id: ID!
  link: Link!
  user: User!
}

This schema allows for the following operations:

  • Queries:

    • feed: Retrieves all links from the backend, note that this query also allows for filter, sorting and pagination arguments
  • Mutations:

    • post: Allows authenticated users to create a new link
    • signup: Create an account for a new user
    • login: Login an existing user
    • vote: Allows authenticated users to vote for an existing link
  • Subscriptions:

    • newLink: Receive realtime updates when a new link is created
    • newVote: Receive realtime updates when a vote was submitted

For example, you can send the following feed query to retrieve the first 10 links from the server:

{
  feed(skip: 0, first: 10) {
    links {
      description
      url
      postedBy {
        name
      }
    }
  }
}

Or the signup mutation to create a new user:

mutation {
  signup(
    name: "Sarah",
    email: "sarah@prisma.io",
    password: "graphql"
  ) {
    token
    user {
      id
    }
  }
}

Deploying the Prisma datamodel

There is one thing left to do before you can start your server and begin sending queries and mutations to it. Prisma needs to be deployed so the GraphQL server can access it.

To deploy Prisma all you need to do is install the server’s dependencies and invoke the prisma deploy command inside the server directory.

The prisma deploy command starts an interactive process.

The Demo server that you used as a deployment target for Prisma is hosed for free in Prisma Cloud and comes with a connected database (AWS Aurora).

Note: You can also omit yarn in the above command if you have the prisma CLI installed globally on your machine (which you can do with yarn global add prisma). In that case, you can simply run prisma deploy.

Exploring the server

Now that Prisma is deployed, you can go and explore the server!

Now you can open a GraphQL Playground by navigation to http://localhost:4000 where the GraphQL server is running.

This creates two new Link records in the database. You can verify that the mutations actually worked by sending the following query in the already open Playground:

{
  feed {
    links {
      id
      description
      url
    }
  }
}

If everything went well, the query will return the following data (the ids will of course be different in your case since they were generated by Prisma and are globally unique):

{
  "data": {
    "feed": {
      "links": [
        {
          "id": "cjcnfwjeif1rx012483nh6utk",
          "description": "The best GraphQL client",
          "url": "https://www.apollographql.com/docs/react/"
        },
        {
          "id": "cjcnfznzff1w601247iili50x",
          "description": "Prisma replaces traditional ORMs and makes it easy to build GraphQL servers 😎",
          "url": "https://www.prisma.io"
        }
      ]
    }
  }
}

Fantastic, your server works! 👏

Unlock the next chapter
Why are there two GraphQL API layers in a backend architecture with Prisma?
To increase robustness and stability of the GraphQL server (if one layer fails, the server is backed by the second one).
To increase performance of the GraphQL server (requests are accelerated by going through multiple layers).
Prisma provides the database layer which offers CRUD operations. The second layer is the application layer for business logic and common workflows (like authentication).
Having two GraphQL layers is a hard requirement by the GraphQL specification.