Understanding Safe Functions

Safe Functions are rules which can be accessed by any other rules, but they always execute on the server, not on the client.  Since your Snap code remains server-side, and is not sent to a web browser for client-side execution, your Snap logic is "safe" and cannot be exposed to the end-user.  They only see the result, not how it was calculated.

Other functions also execute on the server-side, such as sending emails, making database calls, and calculating pricing.  The Snap blocks for these functions only appear within code that runs server-side.

 

Keep your application secure.

Remember the Snap rules you write for your configurator or scene are executed in one of two places: either server-side within the cloud, or client-side within the user's browser.  Consider the best location to balance needs for security and speed.

  • Server Side
    Server-side code is executed on the server, and the results sent to the client. The Snap code itself is never sent to the user's device for execution. Server-side code is best for any proprietary calculations or patented, sensitive lookups. However, network latency does make this code slower.
    Examples: pricing rules, workflow rules, safe functions, global functions.
  • Client Side: 
    Most other code is processed within the web browser on the user's device.  Local to the user with no network latency, client-side code is fast and responsive.  However, it is not as secure: some users could expose the logic within the rule, as they can with any client-side javascript.  Local rules are the best place for code which runs often, needs to be fast, and does not contain sensitive calculations.
    Examples: configurator rules, scene rules, global rules, etc.

You can easily mix and match your code, placing sensitive functions on the server and other code locally. Learn more about where Snap rules are executed.


Managing Safe Functions

In the Admin interface, browse to Resources > Safe Functions

  • To create a new safe function, click the "+Add" button at the bottom of the window.
  • To edit an existing one, click the name of that function in the list.
  • To test a safe function, click the "test" triangle to the right of its name in the list.
  • To delete or clone, check the box next to the safe function/s you want to delete or clone, then click the appropriate button at the bottom of the window.

Testing Safe Functions

Safe functions can be tested by either...

  1. When viewing the list of all safe functions, clicking the "Test" triangle shown to the right of the function's name.
  2. When editing a specific safe function, clicking the "Test" button on the bottom of the editing page.  The safe function will be saved before it is tested.

Example 1: a basic safe function

Either way, a new test window will appear.  The input parameters (if any) are shown and can be edited before clicking the "Test" button which will run your function.  The parameters sent are in JSON format, and the result will also be in JSON format if its return type is an object. If the safe function results in an error, the error will be displayed.

  1. Note the first line of the safe function. We declare the name as "CelsiusFromFarenheit", and define the type of the function as a number.  We also give an optional description, which appears in the safe function list.
  2. Note the second line, where we define the one input parameter, a number value called "Farenheit".  This parameter line is created by clicking the mutation "+" icon seen on the first line.  You can create as many input parameters as you need by clicking that mutation icon.  To remove an input parameter, click the trash can icon.
  3. We add some comments, just to help ourselves remember the formula and some test data.
  4. the last line includes the "return" block.  Every function must have at least one of these to return a value.

 

Example 2: a database query

One of the most common uses for safe functions is a wrapper around database queries.


A test of this function gives these results:

(Learn more about Database Tables.)

Example 3: best practices

When writing safe functions, consider adding these enhancements to make sturdy code that scales well and is easy to maintain.

  • Comments that include test strings.
    Make it easy to test your safe function by pasting example test parameters into comments.  That way, you can simply copy the test parameters, click "test code", paste your params into the tester, and see your results.  Here, for example, we want to test out both good data, as well as the two error messages we built.
  • Tests for bad input data.
    You never know what information may be passed into your function.  Perform a reality-check on your input parameters by feeding them bad data before you use them for processing.
  • Informative results for bad data.
    The function above, if given bad data, simply returns null.  This is acceptable, but consider returning more information to help the calling routine.  Set an error flag to true, or return a more informative message.

After considering these 3 types of enhancements, here's our improved version of the example above:

(for more information on this database query safe function, and to see it work yourself, follow this walkthrough.)

Contexts for Functions

Epicor CPQ has different places where you can store function logic. Which one is best? While every application is different, consider these guidelines:

What does the function do? From where is it called? Function Location
Snap code that can run locally From only one place,
in only one configurator.

Define your function in that same rule type, so it's easy to maintain.

Snap code that can run locally From many places
in only one configurator.
Define your function in a "global" rule type, so it's visible throughout the configurator.
Snap code that can run locally From many configurators.

For best user experience:
If performance needs to be fast, then define it as a global rule in a configurator, then copy/paste into other configurators.  For example, name the global rule "Useful Function Library v1.0".  In exchange for speed, you assume some responsibility as an administrator to ensure any updates to the function library in one configurator are distributed across the configurators.  Editing the name of the rule (to "v1.1", for example) can help highlight differences.  

For best administrator experience:
If the risk of your code forking between two or more configurators is too great, then define your logic as a safe function or .  You'll know every configurator is using this same function, and your code exists only once.  In exchange for this administrator convenience, your users will now have slightly slower performance as the safe function (stored on the server) is queried and internet latency will be part of their experience.

Snap code that can only be performed on a server, such as 

  • querying a database
  • sending emails
  • calling a web service
Anywhere
Define it as a safe function.

Remember, safe functions can be called from anywhere.  So if your configurator needs information from a database, simply query the database from a safe function, and then call that safe function from your configurator.  Here's a walkthrough example.

Safe functions are web services

When you create a safe function, you're also creating a web service.  In other words, the safe functions you build can be called by any other authenticated server anywhere on the internet.   Learn more about our Rest API, which securely exposes information in Epicor CPQ for your use in other systems.

Was this article helpful?