GraphQL quick start

Get started with GraphQL

GraphQL is an open source data query and manipulation language that provides declarative schema definitions and a composable query syntax. By design, GraphQL eliminates over- and under-fetching of relational data, which minimizes network and memory use for clients.

Resources

This tutorial, and other GraphQL topics covered within this documentation, provides details of the Fauna GraphQL API. For more general information about GraphQL, training, or the specification itself, see these resources:

To learn more about the Fauna GraphQL API, see the GraphQL reference, which includes details on the API’s endpoints, directives, input types, relations, and user-defined functions.

GraphQL tutorial

This tutorial demonstrates how to get started with GraphQL, including designing an initial schema, importing that schema into Fauna, adding a few documents, and then running a GraphQL query to retrieve those documents. Start to finish, these steps should only take a few minutes to complete.

The steps:

  1. Log in to Fauna

    Visit https://dashboard.fauna.com/ in your web browser, and log in.

    The Fauna dashboard

  2. Create a GraphQL database

    Let’s create a new database to hold our GraphQL data. Any database would work, but this keeps your GraphQL experiments separate.

    Click New Database, enter graphql into the Database Name field, and press Return (or click SAVE).

    The new graphql database

  3. Create a GraphQL schema

    A GraphQL schema defines the "shape" of the data that can be managed and queried, including all of the fields and their types. We are going to start with a very basic schema for a "todo" list, where each todo item is just a title and a flag to indicate whether the item is complete or not. The schema also defines the kinds of queries that we want to run.

    Create a file called schema.gql containing the following content:

    type Todo {
       title: String!
       completed: Boolean
    }
    
    type Query {
       allTodos: [Todo!]
       todosByCompletedFlag(completed: Boolean!): [Todo!]
    }
  4. Import the GraphQL schema

    Before we can perform any GraphQL queries, we need to import the schema into Fauna. Once we do so, the Fauna GraphQL API automatically creates the necessary classes and indexes to support the schema.

    Click GRAPHQL in the left sidebar.

    The Import your <mark>GraphQL</mark> schema page

    Click IMPORT SCHEMA, which opens your browser’s file selector. Select the schema.gql file, and click the file selector’s Open button. The GraphQL Playground screen is displayed:

    The <mark>GraphQL</mark> Playground screen

  5. Create a document

    Even though our schema has been imported, there are no documents yet. Let’s create one. Copy the following GraphQL mutation query into the left panel of the GraphQL Playground screen:

    mutation CreateATodo {
       createTodo(data: {
       title: "Build an awesome app!"
       completed: false
       }) {
           title
           completed
       }
    }

    Then click the "Play" button (the circle with the right-facing triangle). The query should execute and the response should appear in the right panel:

    {
      "data": {
        "createTodo": {
          "title": "Build an awesome app!",
          "completed": false
        }
      }
    }

    The GraphQL Playground screen should now look like this:

    Created a document in <mark>GraphQL</mark> Playground

  6. Fetch all documents

    Now that we have a document that can be fetched, let’s run a query to fetch all documents. Copy the following GraphQL fetch query:

    query FindAllTodos {
      allTodos {
        data {
          _id
          title
          completed
        }
      }
    }

    Then click the "new tab" + button in the GraphQL Playground screen (at the top left, just right of the CreateATodo tab). Then paste the query into the left panel, and click the "Play" button. The query should execute and the response should appear in the right panel:

    {
      "data": {
        "allTodos": {
          "data": [
            {
              "_id": "235276560024732167",
              "title": "Build an awesome app!",
              "completed": false
            }
          ]
        }
      }
    }

    GraphQL Playground should now look like this:

    Results of a document search in <mark>GraphQL</mark> Playground

How Fauna solved n+1, or why FQL + GraphQL = Emoji: heart rocket

While GraphQL famously solves the over-fetching and under-fetching of traditional REST APIs, it sometimes causes another serious problem: too many round trips to the server, AKA the notorious "​n+1 problem". Typically, there are two approaches to solve this:

  • The first is query batching/caching with a data loader, but such tools introduce complexity and don’t solve the entire problem. You still end up with more than one round trip to the server.

  • The second is to generate one query from each GraphQL query, but this sometimes results in a monster join that can choke traditional SQL databases. Instead of relying on joins, Fauna uses a strategy more akin to what graph databases call index-free adjacency. By nesting Map/Get queries, FQL maps perfectly on the execution plan of a GraphQL query, efficiently walking down the GraphQL tree and retrieving nested documents.

In other words, any given query you send to the GraphQL API always incurs only one single request to the database, and does so efficiently. For a more in-depth explanation, with examples, see our blog post.

Practice more GraphQL queries and their FQL equivalents

Run these queries using the GRAPHQL screen.

Run these queries using the SHELL screen.

Create a product

mutation {
  createProduct(data: {
    name: "Lemon",
    description: "Organic, per each",
    price: 0.35,
    quantity: 100,
    store: { connect: "301" },
    backorderLimit: 10,
    backordered: false,
  }) {
    _id
  }
}
Create(
  Collection("products"),
  {
    data: {
      "name": "Apple",
      "description": "Gala, per each",
      "price": 0.89,
      "quantity": 1000,
      "storeId": Ref(Collection("stores"), "301"),
      "backorderLimit": 10,
      "backordered": false,
    }
  }
)

Read all products

query {
  allProducts {
    data {
      _id
      name
      description
      price
      quantity
      backorderLimit
      backordered
    }
  }
}
Map(
  Paginate(
    Documents(Collection("products"))
  ),
  Lambda("each_ref", Get(Var("each_ref")))
)

Update a store

mutation {
  updateStore(
    id: "301",
    data: {
      name: "DC Fruits R Us"
    }
  ){
    _id
  }
}
Update(
  Ref(Collection("stores"), "301"),
  {
    data: {
      "name": "DC Fruits FTW"
    }
  }
)

Read a store

query {
  findStoreByID(id: "301") {
    _id
    name
    address {
      street
      city
      state
      zipCode
    }
  }
}
Get(Ref(Collection("stores"), "301"))

Delete a product

mutation {
  deleteProduct(id: "203") {
    _id
  }
}
Delete(Ref(Collection("products"), "208"))

Call a UDF to submit an order

mutation {
  submitOrder(
    customerId: "101",
    products: [
      {
        productId: "201",
        quantity: 1
      }
    ]
  ){
    _id
  }
}
Call(
  Function("submit_order"),
  "101",
  [
    {
      productId: "204",
      quantity: 1
    },
    {
      productId: "205",
      quantity: 1
    }
  ]
)

Conclusion

You have now seen how to prepare Fauna for GraphQL queries, how to create and import a GraphQL schema, how to use the GraphQL Playground screen to create and query data. You are now ready to continue your GraphQL journey!

Was this article helpful?

We're sorry to hear that.
Tell us how we can improve!
Visit Fauna's Discourse forums or email docs@fauna.com

Thank you for your feedback!