Chapter IV. - JEXL Public API Functions
This chapter describes how to call public API functions from JEXL expressions in the tSM platform.
Public API calls allow you to access data from individual microservices directly in your expressions, using a service/entity/method convention that is intentionally aligned with Spring Expression Language (SpEL) style method and property access.
1. General Concept
Public API functions are exposed in JEXL in the following form:
<service>.<entity>.<method>(arguments...)
<service>– logical name of a microservice (for examplecrm).<entity>– domain entity or aggregate within that microservice (for examplecustomer).<method>– operation exposed for the entity (for exampleget,find,search, etc.).
The expression is evaluated in the same way you would call a method in SpEL: dot-separated navigation and a method call with parentheses around arguments.
2. Request & Caching Behaviour
- Every public API call triggers a request to the corresponding microservice.
- The platform may cache responses for the same call according to configuration, so repeated evaluation of the exact same expression can reuse a previously fetched response.
- Unless specified otherwise, you can assume that calls are cacheable and the platform will avoid unnecessary duplicate requests where possible.
- If caching is explicitly disabled for a given context or call, each evaluation will result in a new request to the microservice.
When designing expressions, always keep in mind that every such call is a potential remote request and can impact performance and latency.
3. Service / Entity / Method Structure
3.1 Service (microservice)
The first segment before the first dot represents a specific microservice:
crm
Examples of typical services (names are illustrative):
crm– CRM microservicebilling– Billing microserviceticket– Ticketing microservice- ...
3.2 Entity
The second segment is a concrete entity exposed by that microservice:
crm.customer
This is usually a business object or aggregate, such as:
customeraccountlead- ...
The available entities always depend on the particular microservice and its public API.
3.3 Method
The third segment is a method that is invoked on the entity:
crm.customer.get(...)
crm.customer.find(...)
Typical patterns include:
get– retrieves a single entity instance by its unique identifier.find– retrieves a single entity instance based on a search criterion (for example a business key or code).
Other methods can be available depending on the specific microservice. Consult the corresponding service/API documentation for the full list of operations.
4. Examples
4.1 Get customer by ID
crm.customer.get($value.customerId)
crm– CRM microservice.customer– customer entity.get– method that loads a single customer by identifier.$value.customerId– identifier taken from the current context ($value).
Each evaluation of this expression will perform a request to the CRM service. The response can be reused from cache depending on platform configuration and caching settings.
4.2 Find customer by business code
crm.customer.find({ code: $value.customerCode })
- The argument is an object literal with a
codefield. crm.customer.find(...)uses the provided fields as search criteria (for example, business/customer code).- The result is typically a single matching customer or
nullif no record is found (exact behaviour depends on the service contract).
Again, evaluating this expression triggers a request to the CRM microservice, possibly served from cache if caching is enabled and the same call was made before.
4.3 Get account by ID
crm.account.get($value.accountId)
This example is analogous to the customer example, but targets the account entity in the CRM microservice.
crm– CRM microservice.account– account entity.get– method that loads a single account by identifier.$value.accountId– identifier taken from the current context ($value).
Again, evaluating this expression performs a request to the CRM service, potentially served from cache depending on configuration.
4.4 Get account by business code using the IN operator
crm.account.find({ code__in: $value.accountCode })
- The argument is an object literal with a filter key
code__in. - The
__insuffix corresponds to theinfilter operator (see the filter operators list below). $value.accountCodeis typically a list/array of codes; the underlying request is translated to a query like?code__in=["AAA","AA"].
This allows you to retrieve an account whose code is contained in the provided list of values.
4.5 Get register value by ID
config.registerValue.get($value.regValId)
config– configuration microservice.registerValue– register value entity.get– loads a single register value by identifier.$value.regValId– identifier taken from the current context.
As with other calls, this expression triggers a request to the config microservice and can be served from cache depending on configuration.
4.6 Get register value with additional query parameters
config.registerValue.get($context.entity.id, { expand: ['REGISTER'] })
The second argument of the get method is an object that is translated to additional query parameters for the underlying HTTP request.
- The first argument (
$context.entity.id) is the primary identifier. - The second argument (
{ expand: ['REGISTER'] }) is mapped to something like?expand=REGISTER(or a comma-separated list if multiple values are provided). - You can use this pattern for passing expansions, additional filters, sorting options, and similar parameters supported by the given API.
This pattern is generally available for public API calls that accept extra query parameters as a second object argument.
5. Relation to SpEL Syntax
The syntax for public API calls in JEXL is intentionally aligned with SpEL:
- Dot-separated navigation to services and entities:
crm.customer. - Method invocation with parentheses:
crm.customer.get(...). - Use of literals, objects, and variables (for example
$value.customerId) in argument lists.
If you are familiar with SpEL, calling public API functions in JEXL should feel natural and follow the same mental model.
6. Filter operators
Public API filters use a suffix convention on field names, for example code__in or amount__gte.
In JEXL, these appear as object keys, while on the HTTP level they are translated to query parameters.
Example:
crm.account.get({ code__in: ['AAA', 'AA'] })
// -> ?code__in=["AAA","AA"]
Below is an overview of all supported operators (based on the FilterOperator enum):
contains- Description: property contains the provided value (case-insensitive).
- JEXL key:
name__contains. - Query example:
?name__contains=foo.
notcontains- Description: property does not contain the provided value (case-insensitive).
- JEXL key:
name__notcontains. - Query example:
?name__notcontains=foo.
startswith- Description: property starts with the provided value (case-insensitive).
- JEXL key:
name__startswith. - Query example:
?name__startswith=foo.
endswith- Description: property ends with the provided value (case-insensitive).
- JEXL key:
name__endswith. - Query example:
?name__endswith=foo.
in- Description: property is contained in the provided list of values.
- JEXL key:
code__in. - Query example:
?code__in=["AAA","AA"].
notin- Description: property is not contained in the provided list of values.
- JEXL key:
code__notin. - Query example:
?code__notin=["AAA","AA"].
eq- Description: property equals the provided value.
- JEXL key:
status__eq. - Query example:
?status__eq=ACTIVE.
noteq- Description: property does not equal the provided value.
- JEXL key:
status__noteq. - Query example:
?status__noteq=ACTIVE.
gt- Description: property is greater than the provided value.
- JEXL key:
amount__gt. - Query example:
?amount__gt=24.
gte- Description: property is greater than or equal to the provided value.
- JEXL key:
amount__gte. - Query example:
?amount__gte=24.
lt- Description: property is less than the provided value.
- JEXL key:
amount__lt. - Query example:
?amount__lt=24.
lte- Description: property is less than or equal to the provided value.
- JEXL key:
amount__lte. - Query example:
?amount__lte=24.
empty- Description: property is empty (no value set).
- JEXL key:
field__empty. - Query example:
?field__empty.
notempty- Description: property is not empty.
- JEXL key:
field__notempty. - Query example:
?field__notempty.
btw- Description: property is between two provided values (inclusive, unless defined otherwise by the API).
- JEXL key:
amount__btw. - Query example:
?amount__btw=10-15.
gtr- Description: property is greater than current time, relative (for example
-1dfor "1 day ago"). - JEXL key:
date__gtr. - Query example:
?date__gtr=-1d.
- Description: property is greater than current time, relative (for example
ltr- Description: property is less than current time, relative (for example
+1dfor "in 1 day"). - JEXL key:
date__ltr. - Query example:
?date__ltr=+1d.
- Description: property is less than current time, relative (for example
btwr- Description: property is between two relative time values.
- JEXL key:
date__btwr. - Query example:
?date__btwr=-1d:+1d(the exact format can depend on the API contract).
dontTouch- Description: special operator that tells the system not to modify the value.
- Typical usage is for advanced/custom filters where the value is already a full expression.
- Example object:
{ field__dontTouch: 'customFunction()' }. - This is primarily relevant in UI/configuration layers where filter objects are built programmatically.
fuzzyContains(~=)- Description: property approximately/"fuzzily" contains the provided value.
- Only for Elastic TQL use-cases.
- JEXL key:
name__fuzzyContains. - Query example:
?name~=foo(exact format may depend on Elastic/TQL configuration).
These operators can be freely combined with entities and fields that support filtering in the corresponding microservice public API.