Write custom logic with UDFs

Fauna supports user-defined functions (UDFs) for encapsulating business logic as manageable and maintainable resources. UDFs are equivalent to SQL stored procedures.

A UDF is an anonymous function with the same calling syntax as the JavaScript arrow function expression.

UDFs support JavaScript’s rest parameter syntax (…​). See Rest parameters.

See User-defined functions in the migration document for FQL v10 and FQL v4 UDF interoperability.

Create a UDF and call it

This example UDF calculates the circumference of a circle.

  1. Create the UDF by calling the Function Function.create() method, passing the name and a body of the UDF:

    Function.create({
      name: "getCircumference",
      body: "radius => 2 * Math.PI * radius"
    })
    {
      name: "getCircumference",
      coll: Function,
      ts: Time("2023-06-03T18:17:04.285Z"),
      body: "radius => 2 * Math.PI * radius"
    }
  2. Call your UDF by its name, passing a parameter:

    getCircumference(12)
    75.39822368615503
  3. To view the UDFs you defined, call Function.all():

    Function.all()
    {
      data: [
        {
          name: "getCircumference",
          coll: Function,
          ts: Time("2023-06-03T18:19:56.530Z"),
          body: "radius => 2 * Math.PI * radius"
        }
      ]
    }

Call a UDF from a built-in function

Many built-in methods, such as where(), accept a function as input.

This exercise uses the where() method to query your CoffeeBean documents to get the owner information of all owners growing the Robusta coffee bean species.

  1. First, create a UDF that takes declares a species parameter, searches the documents in your collection, and returns Country_of_Origin and Owner fields of the matching documents:

    Function.create({
      name: "getRobustaInfo",
      body: "species => CoffeeBean.all()
                          .where( .Species == species ) {
                            Country_of_Origin,
                            Owner
                          }"
    })
    {
      name: "getRobustaInfo",
      coll: Function,
      ts: Time("2023-06-03T18:40:17.390Z"),
      body: <<-END
        species => CoffeeBean.all()
                              .where( .Species == species ) {
                                Country_of_Origin,
                                Owner
                              }
      END
    }

    Notice that the function body is saved as a heredoc string enclosed by END tags.

  2. Call your UDF with a parameter value of the coffee species you’re interested in:

    getRobustaInfo("Robusta")
    {
      data: [
        {
          Country_of_Origin: "India",
          Owner: "nishant gurjer"
        }
      ]
    }

    It should return only one document with the matching species.

  3. Again, call the Function.all() method to view your UDFs:

    Function.all()
    {
      data: [
        {
          name: "getCircumference",
          coll: Function,
          ts: Time("2023-06-03T18:19:56.530Z"),
          body: "radius => 2 * Math.PI * radius"
        },
        {
          name: "getRobustaInfo",
          coll: Function,
          ts: Time("2023-06-03T18:40:17.390Z"),
          body: <<-END
            species => CoffeeBean.all()
                                  .where( .Species == species ) {
                                    Country_of_Origin,
                                    Owner
                                  }
          END
        }
      ]
    }

    You should see the UDFs created in this exercise.

Delete a UDF

You can reference a UDF instance by the name you assigned it when you created it. Use the Function.byName() method to get the UDF document and chain the Document delete() method to delete the UDF:

Function.byName("getCircumference")!.delete()
Function.byName("getCircumference") /* not found */

The not found string returned in the response indicates that the UDF is successfully deleted, which you can verify by calling the Function.all() method. An error message is returned if the requested UDF doesn’t exist or another function depends on it.

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!