Skip to content

Design an IFS integration middleware layer

Explore this learning path

Documentation-based guide draft · Reviewed against sources on 2026-09-27 · Not executed in an IFS environment. IFS references use 26R1 unless stated otherwise. Confirm available APIs, components, and permissions in your installed release.

Build a small local file worker that forwards an approved message to IFS and saves the response. This makes the middleware’s responsibilities concrete before you implement the same contract in WSO2, another integration platform, or a managed queue service.

Install a supported Node.js version with built-in fetch. Prepare an approved HTTPS IFS inbound endpoint and an accepted JSON fixture. The worker below performs one attempt, saves a receipt, and does not automatically retry. It is a teaching worker, not a durable production queue.

Create ifs-worker-lab, put the validated JSON message in message.json, and choose a stable messageId. Obtain a short-lived token for the intended service identity using authentication.

Set IFS_INBOUND_URL and IFS_ACCESS_TOKEN in your terminal/process environment through your approved local secret mechanism. Never commit them into the worker file. The endpoint must be fixed by configuration, not supplied by the message.

Save send-once.mjs:

import { readFile, writeFile, access } from 'node:fs/promises';
const [inputFile, receiptFile] = process.argv.slice(2);
if (!inputFile || !receiptFile) throw new Error('Usage: node send-once.mjs input.json receipt.json');
const endpoint = new URL(process.env.IFS_INBOUND_URL);
if (endpoint.protocol !== 'https:') throw new Error('HTTPS endpoint required');
const token = process.env.IFS_ACCESS_TOKEN;
if (!token) throw new Error('Missing IFS_ACCESS_TOKEN');
const text = await readFile(inputFile, 'utf8');
if (Buffer.byteLength(text) > 65536) throw new Error('Lab message exceeds 64 KiB');
const message = JSON.parse(text);
if (!/^[A-Z0-9-]{1,64}$/.test(message.messageId ?? '')) throw new Error('Invalid messageId');
try {
await access(receiptFile);
throw new Error('Receipt already exists: reconcile it before replay');
} catch (error) {
if (error.code !== 'ENOENT') throw error;
}
await writeFile(receiptFile, JSON.stringify({
messageId: message.messageId, state: 'attempt-started', at: new Date().toISOString()
}), { flag: 'wx' });
try {
const response = await fetch(endpoint, {
method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15000),
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
body: text
});
const body = await response.text();
await writeFile(receiptFile, JSON.stringify({
messageId: message.messageId,
state: response.ok ? 'http-accepted' : 'http-rejected',
status: response.status, body
}, null, 2));
if (!response.ok) process.exitCode = 1;
} catch (error) {
await writeFile(receiptFile, JSON.stringify({
messageId: message.messageId, state: 'outcome-unknown', error: error.name
}, null, 2));
throw error;
}

Keep the workspace private: the response may contain business data. The receipt is created before sending, so a second invocation using the same receipt path refuses to resubmit. This is a local guard, not a substitute for receiver-side idempotency or a shared production store.

3. Run one attempt and inspect both systems

Section titled “3. Run one attempt and inspect both systems”

Run:

node send-once.mjs message.json receipt-LAB-051.json

Open the receipt. For http-accepted, follow the response’s message/status reference and verify the IFS business result. For http-rejected, diagnose the status/body. For outcome-unknown or attempt-started, search IFS by the original message reference before any replay.

Keep the original message immutable. Write a pure mapping function that produces the receiver’s schema and test it with fixtures before the sender runs. Use XSLT for XML mappings or a tested Java/Node component for another format.

Save mapping version and message ID in production processing records. Avoid performing remote business writes inside a transformation; it makes replay and fault diagnosis harder.

5. Move the proven contract into your middleware platform

Section titled “5. Move the proven contract into your middleware platform”

For WSO2 or another platform, configure a fixed endpoint, secure credential reference, schema validation, bounded timeout, persistent queue, and an error/reconciliation destination matching the states above. Use its supported runtime and deployment model; do not import an old connector merely because its name mentions IFS.

The production implementation needs atomic message claiming, persistent duplicate keys, token renewal, bounded response sizes, controlled retries, and concurrent-worker coordination. Prove each using the same fixtures rather than treating a successful container health check as business acceptance.

Test invalid JSON, missing token, an HTTP rejection, timeout, and a second run with the same receipt filename. Confirm that the local replay guard blocks the second run and that no automatic retry occurs.

After collecting evidence, clear the token from the process environment, stop lab producers, and remove private receipts according to your retention rules. Revoke any dedicated lab credential. Leave unresolved receipts intact until their business outcome is reconciled.

Older IFS Applications examples are historical context, not evidence of Cloud compatibility. No third-party code, screenshots, or downloadable workflows are reproduced.