Rate this page:
The module creates a new custom JQL function, which appears built-in from the user’s perspective - it’s visible in the editor and shows up in the autocomplete dropdown. However, the function’s business logic is executed within the app codebase. Therefore, it’s important to have a basic understanding of how custom JQL functions work in Jira.
Calling an app to evaluate a custom function may be slow. Therefore, instead of doing it on every call, we only evaluate each custom function once and save the result to the database. A stored mapping between a custom function call and native JQL is called a precomputation. To limit the number of stored precomputations which must be updated by apps, they’re deleted from the database after their TTL of one week expires.
App must define the business logic for the custom function that will be invoked by Jira. The custom function should return a valid JQL fragment that can later replace the function clause in the original query.
App should keep precomputations up to date. For this purpose, we're exposing the new Precomputation API to browse stored precomputations and update them if needed. Each precomputation will contain metadata, such as the last time the function was used, which you can use to guide update logic.
The best approach is to update precomputations as a reaction to a related product event/webhook, for example when a new issue is created. Please refer to our Forge example app to see some patterns and strategies to optimize precomputation updates.
The app will be called whenever the function needs to be evaluated. It's expected to return a JQL fragment that the function clause will be replaced with.
The argument that functionKey
will receive looks like this:
1 2{ "precomputationId": "<uuid>" "clause": { "field": "key", "type": [ "issue" ], "operator": "in", "functionName": "issuesWithText", "arguments": [ "Test" ] } }
Note that type
is the type of the field the function is executed against. In this case it’s the same as the field name, which may be confusing. However, imagine a function that works with users - we’d have field: assignee
and type: user
.
precomputationId
is also sent as an input argument. It allows the app to store this UUID internally, which means it doesn’t have to fetch precomputations just to get the correct ID.
The response that the function is supposed to return can be either
1 2{ "error": "Error message returned by app." }
1 2{ "jql": "id in (1, 2, 3)" }
To improve the performance of functions that return a list of issues, enumerate their IDs in your JQL query like id in (1, 2, 3...)
. While using keys may feel more natural, we recommend enumerating by IDs because it can make the operation faster.
There is a limit of 1,000 right-hand side values in the JQL fragment returned by custom functions.
If your app defines a function whose name matches that of a built-in JQL function, it won’t work.
Also keep in mind that during JQL search processing, built-in functions always have higher priority than app-defined ones.
If multiple apps define a JQL function with the same name, the one invoked during query processing is picked randomly.
Here are a few example Forge and Connect apps to help you learn about the JQL function module:
Rate this page: