Server-Side Behaviours
While the primary Behaviours engine uses UI Modifications (client-side), ScriptForge also supports server-side behaviour logic that executes in the Forge backend. This is used for scenarios requiring data lookups, REST API calls, or complex validation that can't run purely in the browser.
When to Use Server-Side Logic
| Scenario | Client (onInit/onChange) | Server (makeRequest) |
|---|---|---|
| Show/hide a field | ✅ | Not needed |
| Set a default value | ✅ | Not needed |
| Look up data from another issue | ❌ | ✅ Use makeRequest |
| Validate against external data | ❌ | ✅ Use makeRequest |
| Check user permissions/groups | ❌ | ✅ Use makeRequest |
Using makeRequest in Behaviours
The makeRequest(path, options) function lets you call Jira REST APIs from within a behaviour script:
// Look up the project lead and auto-assign
const response = await makeRequest('/rest/api/3/project/' + context.projectKey);
const lead = response.body.lead;
fields.assignee.setDefault(lead.accountId);
fields.assignee.setDescription(`Project lead: ${lead.displayName}`);
Parameters
| Parameter | Description |
|---|---|
path |
Jira REST API path (e.g., /rest/api/3/issue/PROJ-123) |
options |
Request options: { method: 'GET', headers: {...}, body: {...} } |
Examples
Fetch user groups to conditionally show fields:
const me = await makeRequest('/rest/api/3/myself');
const groups = await makeRequest(`/rest/api/3/user/groups?accountId=${me.body.accountId}`);
const isManager = groups.body.some(g => g.name === 'managers');
if (isManager) {
fields.getFieldById('customfield_10060').setVisible(true); // Budget field
}
Look up linked issues to set validation:
const links = await makeRequest(`/rest/api/3/issue/${context.issueKey}?fields=issuelinks`);
const hasBlocker = links.body.fields.issuelinks.some(
link => link.type.name === 'Blocks' && link.inwardIssue
);
if (hasBlocker) {
fields.getFieldById('customfield_10070').setRequired(true); // Dependency note
fields.getFieldById('customfield_10070').setDescription('Blocked by another issue — explain the dependency');
}
Performance Considerations
makeRequestadds latency since it calls the Jira API. Keep calls minimal.- Cache results in the script if you need the same data multiple times.
- Avoid calling
makeRequestinonChangehandlers for fields that change frequently (like free text) — use it for select fields or buttons. - The behaviour must complete quickly (sub-second user experience). If you need heavy processing, consider moving that logic to a listener instead.
Error Handling
If makeRequest fails, your script should handle it gracefully:
try {
const response = await makeRequest('/rest/api/3/project/' + context.projectKey);
fields.assignee.setDefault(response.body.lead.accountId);
} catch (err) {
console.error('Failed to look up project lead:', err.message);
// Don't crash — just skip the auto-assignment
}
Logging
Use console.log(), console.warn(), and console.error() for debugging. Output appears in the ScriptForge Execution History and can also be viewed in the browser's developer console (for the client-side portion).