User-defined functions in GraphQL

This tutorial assumes that you have successfully completed the Dashboard quick start tutorial, and that you still have the Fauna Dashboard open in a browser tab/window, on the GraphQL Playground screen.

If your Dashboard session has expired:

  1. Log in again.

  2. Select the graphql database.

  3. Click the GRAPHQL button in the left navigation.

User-defined functions (or UDFs) provide a mechanism to store and run commonly used Fauna queries. After you create a UDF, you can access it with GraphQL by declaring it in your schema with the resolver directive.

This tutorial demonstrates how to create a UDF, declare it in your schema, and use it to perform database operations in the GraphQL Playground. Your schema creates the environment necessary for a basic e-commerce system, with collections for stores, products, customers, and orders.

Tutorial

  1. Create a new schema file

    Create the file schema-products.gql with the following content (or download it here):

    type Store {
      name: String
      address: Address
    }
    
    type Address @embedded {
      street: String
      city: String
      state: String
      zipCode: String
    }
    
    type Product {
      name: String
      description: String
      price: Float
      quantity: Int
      store: Store
      backorderLimit: Int
      backordered: Boolean 
    }
    
    type Query {
       allProducts: [Product!]
       createNewOrder(customerID: String!, productID: String!, qty: Int!): Order! @resolver(name: "submitOrder")
    }
    
    type Customer {
      name: String
      address: Address
    }
    
    type Order {
      customer: Customer
      product: Product
      quantity: Int
    }
  2. Import the new GraphQL schema into Fauna

    Click the REPLACE SCHEMA button on the GraphQL Playground screen in your browser, which opens your browser’s file selector. Select the schema-products.gql file, and click the file selector’s Open button.

  3. Create some records

    1. Before you can use your UDF, you need some data to work with in your collections. First, create a store with the following mutation.

      mutation CreateAStore {
         createStore(data: {
         name: "Specialty Fruits"
         address: {
            street: "431 Maple St NW"
            city: "Providence"
            state: "RI"
            zipCode: "02906"
          }
         }) {
             name
             _id
             address {
              city
            }
         }
      }

      You should see results similar to this:

      {
        "data": {
          "createStore": {
            "name": "Specialty Fruits",
            "_id": "317453362718048328",
            "address": {
              "city": "Providence"
            }
          }
        }
      }
      Use the + button in the GraphQL Playground to create new query tabs. Leaving old tabs open is helpful for retrieving ID fields for use in other queries.
    2. Next, create a new product document with the following mutation. Be sure to replace <store-id> with the ID value from the store you created in the previous step.

      mutation {
        createProduct(data: {
          name: "Lemon",
          description: "Organic, per each",
          price: 0.35,
          quantity: 100,
          store: { connect: "<store-id>" },
          backorderLimit: 10,
          backordered: false,
        }) {
          _id
        }
      }

      You should see results similar to this:

      {
        "data": {
          "createProduct": {
            "_id": "317453513702506569"
          }
        }
      }
    3. Next, create a new customer document with the following mutation:

      mutation CreateACustomer {
        createCustomer(data: {
          name: "Alice Smith"
          address: {
            street: "2728 Brookfield Dr"
            city: "Santa Fe"
            state: "NM"
            zipCode: "87501"
          }
        }) {
          name
          _id
        }
      }

      You should see results similar to this:

      {
        "data": {
          "createCustomer": {
            "name": "Alice Smith",
            "_id": "317453601650769992"
          }
        }
      }

      Now you have a store, a product, and a customer. Time to create an order — but first you need to update your createNewOrder UDF.

  4. Update your UDF

    When you imported your schema, Fauna created the skeleton of a function named createNewOrder, but it doesn’t do anything useful yet. Run the following query in the Dashboard’s Shell to update your function:

    Update(
      Function("createNewOrder"),
      {
        body: Query(Lambda(
          ["customerID", "productID", "qty"],
          Create(
            Collection("Order"),
              {
                data: {
                  customer: Ref(Collection("Customer"), Var("customerID")),
                  product: Ref(Collection("Product"), Var("productID")),
                  quantity: Var("qty")
                }
              }
            )
          )
        )
      }
    )
  5. Call your UDF with a query

    This UDF accepts three inputs: a customer ID, a product ID, and a quantity. Be sure to replace the placeholder values with real values from your earlier GraphQL mutations.

    query {
      createNewOrder(
        customerID: "<customer-id>",
        productID: "<product-id>",
        qty: 50
      ) {
        _id
      }
    }

    You should see results similar to this:

    {
      "data": {
        "createNewOrder": {
          "_id": "317348589049217095"
        }
      }
    }
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: "<store-id>" },
    backorderLimit: 10,
    backordered: false,
  }) {
    _id
  }
}
Create(
  Collection("Product"),
  {
    data: {
      "name": "Apple",
      "description": "Gala, per each",
      "price": 0.89,
      "quantity": 1000,
      "store": Ref(Collection("Store"), "<store-id>"),
      "backorderLimit": 10,
      "backordered": false,
    }
  }
)

Read all products

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

Update a store

mutation {
  updateStore(
    id: "<store-id>",
    data: {
      name: "DC Fruits R Us"
    }
  ){
    _id
  }
}
Update(
  Ref(Collection("Store"), "<store-id>"),
  {
    data: {
      "name": "DC Fruits FTW"
    }
  }
)

Read a store

query {
  findStoreByID(id: "<store-id>") {
    _id
    name
    address {
      street
      city
      state
      zipCode
    }
  }
}
Get(Ref(Collection("Store"), "<store-id>"))

Delete a product

mutation {
  deleteProduct(id: "<product-id>") {
    _id
  }
}
Delete(Ref(Collection("Product"), "<product-id>"))

Call a UDF to submit an order

query {
  createNewOrder(
    customerID: "<customer-id>",
    productID: "<product-id>",
    qty: 1
  ){
    _id
  }
}
Call(
  Function("createNewOrder"),
  "<customer-id>",
  "<product-id>",
  1
)

Conclusion

This tutorial has demonstrated how to create and use a user-defined function (UDF) in a GraphQL query.

For more information about UDFs, see User-defined functions.

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!