Check out v4 of the Fauna CLI

v4 of the Fauna CLI is now in beta.

The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start.

Static typing

See Static typing

FQL is a statically typed query language. Every value has a specific data type. You can only call FQL methods that are valid for a value’s type.

Fauna’s type checking feature helps you catch FQL type mismatches before evaluation. This helps prevent runtime errors that can be hard to diagnose and fix.

Type checking by example

The following examples show Fauna handles FQL queries with type checking enabled and disabled. Examples use the Fauna Dashboard's demo data.

  1. In the Fauna Dashboard, ensure type checking is enabled.

  2. Run the following FQL query to create a document in the Product collection.

    let produce = Category.byName("produce").first()
    
    // Create a document with a specific `id`
    Product.create({
      id: "392886847463751747",
      name: "key limes",
      description: "Organic, 1 ct",
      price: 79,
      stock: 2000,
      category: produce
    })

    The query uses collection.create() to specify a document id. This lets you more easily fetch the document in later examples.

  3. With type checking enabled, attempt to update the document using the following query. The query:

    // Update the document
    Product.byId("392886847463751747")
      .update({
        description: "Organic, 2 ct",
      })

    The query is unsafe and returns an error:

    invalid_query: The query failed 1 validation check
    
    error: Type `Null` does not have field `update`
    at *query*:3:4
      |
    3 |   .update({
      |    ^^^^^^
      |
    hint: Use the ! or ?. operator to handle the null case
    at *query*:2:35
      |
    2 | Product.byId("392886847463751747")!
      |                                   +
      |

    collection.byId() returns a Document or a NullDoc, which indicates the requested document doesn’t exist. NullDocs always contain a null value.

    The query passes this value to document.update(), which only accepts a Document. The query doesn’t safely handle cases in which collection.byId() may return a NullDoc.

    To fix this, you can append one of the following postfix operators to collection.byId():

  4. Add the ?. postfix operator and rerun the query:

    // Update the document
    Product.byId("392886847463751747")
      ?.update({
        description: "Organic, 2 ct",
      })

    The query now runs successfully.

  5. In the Dashboard Shell, click Typecheck to disable type checking.

  6. Rerun the previous unsafe query:

    // Update the document
    Product.byId("392886847463751747")
      .update({
        description: "Organic, 2 ct",
      })

    With type checking disabled, the unsafe query runs successfully. While this may seem more convenient, it adds risk.

    Now, the query won’t return an error until collection.byId() returns a NullDoc. If this does happen, it’s likely to occur later in the development process — possibly when the application is already in production.

  7. To test this out, delete the document and rerun the unsafe query with type checking disabled:

    // Delete the document
    Product.byId("392886847463751747")
      .delete()
    
    // Attempt to update the deleted document
    Product.byId("392886847463751747")
      .update({
        description: "Organic, 2 ct",
      })

    The query now returns an error:

    document_not_found: Collection `Product` does not contain document with id 392886847463751747.
    
    error: Collection `Product` does not contain document with id 392886847463751747.
    at *query*:6:13
      |
    6 | Product.byId("392886847463751747")
      |             ^^^^^^^^^^^^^^^^^^^^^^
      |

Enable type checking for a database

When you can create a database in the Fauna Dashboard, you can enable type checking using the Static Typing option. If wanted, you can later edit the database to change this option.

Enable type checking for a child database

You can enable type checking for a child database using <Database>.update():

Database.byName( "childDB" )
  ?.update(
    { typechecked: true }
  )

The typecheck property set using a Fauna client driver overrides this setting.

Enable type checking in the driver

You can enable type checking in Fauna’s client drivers at two levels:

  • Configure the driver’s client instance to enable type checking on all queries by default. For example:

    ...
    const clientConfig = {
      typecheck: true,
      ...
    };
    
    const client = new Client(clientConfig);
    ...
  • Configure type checking on specific query calls. For example:

    ...
    const queryOptions = {
      typecheck: true,
      ...
    };
    
    const response = await client.query(fql`"Hello World!"`, queryOptions);
    ...

To use type checking in a driver, type checking must be enabled in the database.

Type checking for UDFs and other database entities

If you disable type checking for a database, Fauna does not type check the database’s:

  • User-defined function (UDF) definitions

  • FQL expressions, such as predicate functions, in role and access provider definitions

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!