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

Backend

Since this is a frontend track, you don’t want to spend too much time setting up the backend. This is why you use Graphcool, a service that provides a production-ready GraphQL API out-of-the-box.

The Data Model

You’ll use the Graphcool CLI to build (and deploy) your GraphQL API based on the data model that you need for the app.

Speaking of the data model, here is what the final version looks like written in the GraphQL Schema Definition Language (SDL):

type User @model {
  id: ID! @isUnique     # required system field (read-only)
  createdAt: DateTime!  # optional system field (read-only)
  updatedAt: DateTime!  # optional system field (read-only)

  email: String! @isUnique # for authentication
  password: String!        # for authentication

  name: String!
  links: [Link!]! @relation(name: "UsersLinks")
  votes: [Vote!]! @relation(name: "UsersVotes")
}

type Link @model {
  id: ID! @isUnique     # required system field (read-only)
  createdAt: DateTime!  # optional system field (read-only)
  updatedAt: DateTime!  # optional system field (read-only)

  description: String!
  url: String!
  postedBy: User! @relation(name: "UsersLinks")
  votes: [Vote!]! @relation(name: "VotesOnLink")
}

type Vote @model {
  id: ID! @isUnique     # required system field (read-only)
  createdAt: DateTime!  # optional system field (read-only)

  user: User! @relation(name: "UsersVotes")
  link: Link! @relation(name: "VotesOnLink")
}

As you can see from the comments, some fields on your model types are read-only. This means they will be managed for you by the Graphcool Framework.

In general, there are a few things to note about these type definitions:

  • Every type annotated with the @model-directive will be mapped to the database and corresponding CRUD-operations are added to the GraphQL API of your Graphcool service.
  • The @isUnique-directive means that the annotated field can never have the same value for two different records of that type (also called nodes). Since this is a read-only field, the Graphcool Framework will take care of managing this constraint.
  • createdAt and updatedAt are special fields that are managed by the Graphcool Framework as well. createdAt will carry the date for when a node of that type was created, updatedAt when it was last updated.

Creating the GraphQL Server

For starting out, you’re not going to use the full data model that you saw above. That’s because we want to evolve the schema when it becomes necessary for the features that we implement.

For now, you’ll just use the Link type to create the backend.

The first thing you need to do to get your GraphQL server, install the Graphcool CLI with npm.

To use the Graphcool CLI, you can either use the graphcool-framework command, or the shorter form: gcf.

Now you can go and create the server. There are two steps involved in this:

  1. Creating the local file structure that contains all required configuration for your backend. This is done with the graphcool-framework init command.
  2. Configuring the data model and deploying the server with graphcool-framework deploy.

This will create a new directory called server and place the following files in there:

  • graphcool.yml: This is the root configuration file for your Graphcool service. It tells the Graphcool Framework where to find your data model (and other type definitions), specifies the permission rules and provides information about any integrated serverless functions.
  • types.graphql: This specifies the data model for your application, all type definitions are written in GraphQL SDL.
  • package.json: If you’re integrating any serverless functions that are using dependencies from npm, you need to list those dependencies here. Note that this file is completely independent from the dependencies of your frontend which you’ll create in a bit. Since this tutorial won’t actually use any serverless functions, you can simply ignore it.
  • src: The src directory is used to for the code of the serverless functions you’re integrating in your Graphcool service. It currently contains the setup for a simple β€œHello World”-resolver function (which you can delete if you like). Again, you can ignore this directory since we’re not going to use any functions in this tutorial.

Next you need to make sure that the data model of the GraphQL server is correct, so you need to adjust the type definitions in types.graphql.

As mentioned above, we’ll start with only a sub-part of the actual data model and evolve our schema and API when necessary. This change is all you need to put your GraphQL server into production.

Note that this command will open up a browser window first and ask you to authenticate on the Graphcool platform (if you haven’t done so before).

Populate The Database & GraphQL Playgrounds

Before you move on to setup the frontend, go ahead and create some initial data in the project so you’ve got something to see once you start rendering data in the app!

You’ll do this by using a GraphQL Playground which is an interactive environment that allows you to send queries and mutations. It’s a great way to explore the capabilities of a GraphQL API.

The left pane of the Playground is the editor that you can use to write your queries and mutations (and even realtime subscriptions). Once you click the play button in the middle, the response to the request will be displayed in the results pane on the right.

Since you’re adding two mutations to the editor at once, the mutations need to have operation names. In your case, these are CreateGraphcoolLink and CreateApolloLink.

Clicking the play button

This creates two new Link records in the database. You can verify that the mutations worked by either viewing the currently stored data in the data browser (simply click DATA in the left side-menu) or by sending the following query in the already open Playground:

{
  allLinks {
    id
    description
    url
  }
}

If everything went well, the query would return the following data:

{
  "data": {
    "allLinks": [
      {
        "id": "cj4jo6xxat8o901420m0yy60i",
        "description": "The coolest GraphQL backend 😎",
        "url": "https://graph.cool"
      },
      {
        "id": "cj4jo6z4it8on0142p7q015hc",
        "description": "The best GraphQL client",
        "url": "http://dev.apollodata.com/"
      }
    ]
  }

Frontend

Creating the App

Next, you are going to create the Angular project! As mentioned in the beginning, you’ll use angular-cli for that.

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

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

cd hackernews-angular-apollo
npm install # or yarn
npm start # or yarn start

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

Open a browser to localhost:4200

Your project structure should now look as follows:

.
β”œβ”€β”€ README.md
β”œβ”€β”€ e2e
β”‚   β”œβ”€β”€ app.e2e-spec.ts
β”‚   β”œβ”€β”€ app.po.ts
β”‚   └── tsconfig.e2e.tson
β”œβ”€β”€ karma.conf.ts
β”œβ”€β”€ node_modules
β”œβ”€β”€ package.tson
β”œβ”€β”€ server
β”‚   β”œβ”€β”€ graphcool.yml
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ types.graphql
β”‚   └── src
β”‚       β”œβ”€β”€ hello.js
β”‚       └── hello.graphql
β”œβ”€β”€ protractor.conf.ts
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ app
β”‚   β”‚   β”œβ”€β”€ app.component.css
β”‚   β”‚   β”œβ”€β”€ app.component.html
β”‚   β”‚   β”œβ”€β”€ app.component.spec.ts
β”‚   β”‚   β”œβ”€β”€ app.component.ts
β”‚   β”‚   └── app.module.ts
β”‚   β”œβ”€β”€ assets
β”‚   β”œβ”€β”€ environments
β”‚   β”‚   β”œβ”€β”€ environment.prod.ts
β”‚   β”‚   └── environment.ts
β”‚   β”œβ”€β”€ favicon.ico
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ main.ts
β”‚   β”œβ”€β”€ polyfills.ts
β”‚   β”œβ”€β”€ styles.css
β”‚   β”œβ”€β”€ test.ts
β”‚   β”œβ”€β”€ tsconfig.app.tson
β”‚   β”œβ”€β”€ tsconfig.spec.tson
β”‚   └── typings.d.ts
β”œβ”€β”€ tsconfig.tson
β”œβ”€β”€ tslint.tson
└── yarn.lock

Prepare Styling

This tutorial is about the concepts of GraphQL and how you can use it from within an Angular application, so we want to spend the least time on styling issues. To ease up usage of CSS in this project, you’ll use the Tachyons library which provides some 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.

Installing Apollo

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

  • apollo-client is the Apollo Client library
  • apollo-angular contains the bindings to use Apollo Client with Angular.
  • graphql-tag is a GraphQL parser. Every GraphQL operation you hand over to Apollo Client will have to be parsed by the gql function.
  • apollo-angular-link-http provides a similar HttpLink to Apollo’s HttpLink with one difference, it uses Angular’s HttpClient.
  • apollo-cache-inmemory is a cache implementation that supports all of Apollo Client 1.0’s features without the dependency on Redux.
  • 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! πŸš€

Configuring the ApolloClient

Apollo abstracts away all lower-lever networking logic and provides a friendly interface to the GraphQL API. In contrast to working with REST APIs, you don’t have to deal with constructing your HTTP requests anymore - instead, you can just write queries and mutations and send them using the ApolloClient.

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

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

  1. You’re importing the required dependencies from the apollo-angular, apollo-angular-link-http, apollo-cache-inmemory packages
  2. We export the HttpClientModule, ApolloModule, HttpLinkModule to make them β€œpublic” when GraphQLModule is imported in another module. In fact, if you don’t export, it stays private, visible only to other component declared in this module. You can find more information in NgModule FAQs
  3. We inject the Apollo and HttpLink to be able to configure them
  4. We create a link by providing the URI (i.e. your actual GraphQL endpoint) to the .create method of the HttpLink instance. You’ll replace the placeholder __SIMPLE_API_ENDPOINT__ with your actual endpoint in a bit
  5. Now you instantiate the ApolloClient by passing in the link created and an InMemoryCache cache instance. You can also use new InMemoryCache({ dataIdFromObject: o => (o as GraphCoolObject).id }) and have all your objects in types.ts extend a common interface names GraphCoolObject with an id: string; property to specify how Apollo will identify and de-duplicate the objects returned from the server. The HttpLink is a replacement for createNetworkInterface from Apollo Client 1.0

Finally, we export the GraphQLModule.

Next, you need to replace the placeholder for the GraphQL endpoint with your actual endpoint. But where do you get your endpoint from?

There are two ways for you to get your endpoint. You can either open the Graphcool Console and click the Endoints-button in the bottom-left corner. The second option is to use the CLI.

That’s it; you’re all set to start for loading some data into your app! 😎

Unlock the next chapter
Which are the two types that you find in every Graphcool project file?
File & System
Query & Mutation
User & Group
File & User