Nikolas Burk
Written By
Nikolas Burk
Developer @ Graphcool

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

Getting Started

In this chapter, you’ll define the schema for the application and then build the GraphQL server using the Graphcool CLI.

Defining the schema

The final schema for the backend will look as follows:

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

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

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

There are three types in the schema: User, Link and Vote. Notice that the exclamation point that follows the type of each field means that this field is required.

The User type has a special role in a Graphcool project since it will be used for authentication. You’ll see in a bit why that matters.

In the schema, there are a few relations defined:

  • UsersLinks: A one-to-many-relationship between User and Link that expresses that one User can create zero or more Links, and one Link can only ever have one User
  • UsersVotes: A one-to-many-relationship between User and Vote that expresses that one User can submit zero or more Votes, and one Vote can only ever have one User
  • VotesOnLink: A one-to-many-relationship between Vote and Link that expresses that one Link can have many Votes, but one Vote can only ever be associated with one Link

Note that the @relation directive is specific to Graphcool.

Creating the backend

Before you can create your backend, you first need to install the Graphcool CLI using npm.

Once graphcool is installed, you can go ahead and create the Graphcool project.

This will execute the graphcool init command with two arguments:

  • --schema: This option accepts a .graphql-schema that’s either stored locally or at a remote URL. In your case, you’re using the starter schema stored at https://graphqlbin.com/hn-starter.graphql, we’ll take a look at it in a bit.
  • --name: This is the name of the Graphcool project you’re creating, here you’re simply calling it Hackernews.

Note that this command will open up a browser window first and ask you to authenticate on the Graphcool platform.

The schema that’s stored at https://graphqlbin.com/hn-starter.graphql only defines the Link type for now:

type Link implements Node {
  description: String!
  url: String!
}

Once the project was created, you’ll find the Graphcool Project File (project.graphcool) in the directory where you executed the command. It should look similar to this:

# project: cj4k7j28p7ujs014860czx89p
# version: 1

type File implements Node {
  contentType: String!
  createdAt: DateTime!
  id: ID! @isUnique
  name: String!
  secret: String! @isUnique
  size: Int!
  updatedAt: DateTime!
  url: String! @isUnique
}

type Link implements Node {
  createdAt: DateTime!
  description: String!
  id: ID! @isUnique
  updatedAt: DateTime!
  url: String!
}

type User implements Node {
  createdAt: DateTime!
  id: ID! @isUnique
  updatedAt: DateTime!
}

The top of the file contains some metadata about the project, namely the project ID and the version number of the schema.

The User and File types are generated by Graphcool and have some special characteristics. As mentioned above, User can be used for authentication - File will be used for file management.

Also notice that each type has three fields called id, createdAt and updatedAt. These are managed by the system and read-only for you.

Exploring the project in a Playground

Let’s go and explore the Graphcool project that you just created! The easiest way to do so is by using a Playground that’s integrated directly in the Graphcool console. A GraphQL Playground is an interactive environment that allows you to send queries and mutations. It’s a great way to explore the capabilities of an API.

This command will read the project ID from the project file and open up a Playground in a browser.

Note: Another way to get open up a Playground is by pasting the endpoint of the Simple API or the Relay API into the address bar of a browser. However, using the Playground in the Console provides a few benefits such as an easy way to authenticate requests.

The left pane of the Playground is the editor that you can use to write your queries and mutations (and even 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.

Go ahead and create some initial data in the project! We prepared two mutations for you.

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 CreateRelayLink.

This creates two new Link records in the database. You can verify that the mutations actually 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 will return the following data:

{
  "data": {
    "allLinks": [
      {
        "id": "cj4jo6xxat8o901420m0yy60i",
        "description": "The coolest GraphQL backend 😎",
        "url": "https://graph.cool"
      },
      {
        "id": "cj4jo6z4it8on0142p7q015hc",
        "description": "Facebook's homegrown GraphQL client",
        "url": "https://facebook.github.io/relay/"
      }
    ]
  }

The Graphcool Simple API

As mentioned above, the Graphcool offers a CRUD-style API for all your model types. By default, the following queries will be generated per type:

Query all items

For each model type, you have the ability to retrieve all the instances of that type that are currently stored in the database.

The corresponding query is named all<Type>s. In the example of the Link type, this becomes the allLinks query.

The all-query also accepts a filter object as input argument so you can specify conditions about which objects you want to have returned. In case you want to implement pagination, you can do so using the first, last, skip, limit, before and after arguments.

Query a specific item by its ID

For each type, you have the ability to query a single item of that type by providing an ID.

The query you can use for that is name <Type> and takes as input an id argument. In the case of the Link, the query looks as follows: Link(id: ID!). An example would be:

Link(id: "cj4jo6xxat8o901420m0yy60i") {
  description
  url
}
Creating items

For creating new items on the server, there will be a create<Type> mutation generated for you. For the example of the Link type, you already used this mutation in the Playground.

Note that each create<Type> mutation accepts all the fields of the corresponding type as arguments so you can directly initialize all its properties when it’s created. For types that have relations, you can further use nested mutations and create multiple related nodes at once.

Updating items

Often times, you’ll want the ability to update existing items in the database. For the Link type, a user might want to update the description after it was initially created. In the example, the mutation is called updateLink.

This can be done using the update<Type> mutation. Like the create<Type> mutation, this mutation accepts values for all the fields of the type as arguments so you can update as many properties as you like in a single request. Note however that you also must pass the id of the object you want to update to the mutation - which is logical since you need to tell server which item you want to change.

Deleting items

Finally, you’re of course also able to delete existing items from the database. This can be done using the delete<Type> mutation which only requires the id of the item that is to be deleted as an argument.

For the Hackernews example schema, this mutation is called deleteLink.

Next Chapter

Evolving the Schema with the CLI

Learn best practices for using the Graphcool CLI and how it can be used to evolve to the GraphQL schema.

Go to next chapter