Skip to content

Practical guide

Reuse backend logic with custom functions

Extract repeated Twidget commands into a typed custom function, map inputs and outputs, and test callers without moving browser logic into the backend.

1. Choose one stable piece of shared logic

Use a backend custom function when several endpoints or events need the same explicit operation. This example calculates an order-line total from quantity and unit price in minor currency units. It is a design recipe to configure and test, not an automatically installed function.

Keep the first function small: validate two numbers and return their product. Database reads, customer authorization and notifications remain in the callers initially. If shared logic should always run before or after a workflow, review middleware instead. Explicit function calls and automatic middleware solve different needs.

2. Declare typed inputs and an output

Create a function with number inputs such as quantity and unit_price_minor. Backend function inputs are typed values rather than endpoint Body, Query or Headers inputs. Define the intended bounds, integer requirement and supported maximum total. A Number input alone does not enforce those business rules.

Choose a clear output, for example an object containing line_total_minor. Define an output schema to explain the result to callers. It documents the contract; verify actual behavior with tests. Keep currency explicit in the surrounding order workflow and avoid adding totals across currencies.

3. Build the shared command sequence

Add validation before calculating the total, then map the result into the output. Reject missing values, fractions where whole units are required, negative amounts and totals beyond your supported range. Use Twidget's command picker and variable selector to bind the actual declared inputs.

Do not accept a precomputed client total as authoritative. In a purchase workflow, load the permitted price on the backend and pass that trusted value to the helper. This helper can calculate correctly while its caller still authorizes the wrong record; test both boundaries. See purchase requests for the full application context.

Body input editor with Required checked
Required applies to the Body input as a whole. Validate individual properties and business rules separately; the Object schema is not proof that every desired rule is enforced.

4. Call it from the workflows that need it

Open a caller, use Add Commands → Your Functions and select the helper. Map its inputs explicitly from the caller's variables and give its output a useful return name. Read the returned field when constructing the endpoint response or saving the record.

A page function operates in the browser/page context and is a different kind of function. For a Twidget page, call a protected backend endpoint that performs the calculation; keep backend-only data and secrets there. Watch custom functions and compare custom page functions before choosing the execution context.

5. Test the helper and its callers separately

Helper inputExpected contract
Quantity 3, unit price 1250Total 3750 minor units
Missing quantityValidation failure
Negative priceValidation failure
Total above application maximumValidation failure

Then run each caller with its real mapping. Test a denied customer and a stale price selection, not only arithmetic. Use isolated data for initial checks. A passing direct function test does not establish a published endpoint's permissions or response shape.

API suite editor with a create_request step alias
Existing Marketing test controls. Use dedicated fixtures for this guide; this screenshot does not demonstrate its acceptance cases.
Isolated test with null output, Unsupported event type error and a failed Validate trace
Existing isolated receiver test rejected an unsupported event type. It illustrates a validation failure, not a submitted enquiry form or its field-error response.

6. Review shared changes as a dependency

List callers before renaming an input or changing the output. Prefer a deliberate migration when an old caller still expects a different shape. Save and publish the relevant changes, then exercise the published callers through the API client.

Use a multi-step test suite for workflows that call the helper. If one endpoint behaves differently, inspect input mapping and published state before duplicating the logic again. Reuse earns its value when callers share a clear, verified contract.

Go deeper

Supporting documentation

Find the configuration details and reference material behind this page.

From idea to a working flow

Build one useful thing with Twidget

Start with a small workflow, test it with sample data and make it your own.

Preview

Have any questions? Get in Touch

Starting with Twidget is easy, fast and free

It only takes a few clicks to get started

Get started - it's free

No credit card required.


© Copyright 2026 - Twidget.io