DEV Community

Cover image for Getting Started with GraphQL, Part 3: The Unique Directive
Fauna for Fauna, Inc.

Posted on • Updated on • Originally published at fauna.com

Getting Started with GraphQL, Part 3: The Unique Directive

Author: Chris Anderson
Date: April 30, 2019
Originally published on the Fauna blog.


In the previous two articles we explored how to set up your development environment and query your GraphQL schema, then added relationships to your GraphQL queries. In this article we’ll look at the @unique directive, which allows you to add constraints to your GraphQL schema.

To define a simple user type with a uniqueness constraint on the username, you simply add the @unique directive to the username field, and FaunaDB handles creating the index to enforce this constraint.

type User {
 username: String! @unique
}
Enter fullscreen mode Exit fullscreen mode

Import this schema into FaunaDB by creating a database, provisioning a key secret, and uploading it via curl (for detailed instructions see the first article in this series). Alternatively, you can just reuse the secret from the previous article, and your schema will be safely extended with a User type:

curl -u <key-secret>: https://graphql.fauna.com/import --data-binary "@<graphql-schema-filename>"
Enter fullscreen mode Exit fullscreen mode

Now you can inspect the schema via Fauna Shell or GraphQL Playground. Remember to configure the Authorization header in your GraphQL Playground for the current database.

You can list the classes and indexes in your database by launching the shell and issuing this query. To launch the shell directly into your current database, use the --secret command line flag:

fauna shell --secret=<key-secret>
Enter fullscreen mode Exit fullscreen mode

If you started with an empty database, you’ll only have one class and one index:

> Paginate(Union(Classes(), Indexes()))
Enter fullscreen mode Exit fullscreen mode
{ data: [ Class("User"), Index("unique_User_username") ] }
Enter fullscreen mode Exit fullscreen mode

Now let’s inspect the index with the following query in the Fauna Shell:

> Get(Index("unique_User_username"))
Enter fullscreen mode Exit fullscreen mode
{ ref: Index("unique_User_username"),
  ts: 1556578547300000,
 active: true,
 partitions: 1,
 name: 'unique_User_username',
 source: Class("User"),
 data: { gql: {} },
 values: [],
 terms: [ { field: [ 'data', 'username' ] } ],
 unique: true }
Enter fullscreen mode Exit fullscreen mode

We can see in this response that the FaunaDB index is maintaining a uniqueness constraint on the username field. Trying to create users with duplicate usernames will result in an error. We'll try doing that in GraphQL Playground in a moment.

Now let’s switch to the GraphQL Playground (make sure you configure it with the correct Authorization header), and inspect the generated schema. Here are the relevant domain objects (inspect the schema yourself to see some additional boilerplate):

type Mutation {
 createUser(data: UserInput!): User!
 updateUser(
   id: ID!
   data: UserInput!
 ): User
 deleteUser(id: ID!): User
}

type Query {
 findUserByID(id: ID!): User
}

type User {
 _id: ID!
 _ts: Long!
 username: String!
}

input UserInput {
 username: String!
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Create a new user by pasting the following query and pressing the "Play" button:

mutation CreateAUser {
   createUser(data: {
     username: "Alice"
   }) {
     username
   }
}
Enter fullscreen mode Exit fullscreen mode

You should receive the following response:

{
  "data": {
    "createUser": {
      "username": "Alice"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, let's try adding a duplicate user. Simply click the "Play" button to run the same query again. This time, you should get an error:

{
  "errors": {
    "message": "Instance is not unique.",
    "extensions": {
      "code": "instance not unique"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This tutorial has demonstrated how to apply uniqueness constraints to your data with the @unique directive. Stay tuned for more about GraphQL and FaunaDB, as we explore schema updates, access control, and custom schema elements.

Top comments (0)