Resource Hook Integration Guide (SDK version >= 3.3.0)¶
Overview¶
Resource Hook allows you to append request-level business context to automatically collected resource events.
Use cases:
- Writing business context before the request is sent
- Adding additional fields after the response is received
- Ensuring the final
resourceevent includes both sets of data
This capability supports both fetch and XMLHttpRequest.
How It Works¶
- Create a tracker ID with
createResourceTrackerId() - Attach this ID to the request header
x-rum-resource-id - Use
setResourceContext()to write pre-request context - Use
appendResourceContext()to append post-response context - Call
finishResource()to trigger the final tracked resource upload
If the request does not carry x-rum-resource-id, the SDK falls back to the normal automatic resource collection flow.
Public API¶
const resourceId = DATAFLUX_RUM.createResourceTrackerId()
DATAFLUX_RUM.setResourceContext(resourceId, { order_id: '123' })
DATAFLUX_RUM.appendResourceContext(resourceId, { result: 'success' })
DATAFLUX_RUM.finishResource(resourceId)
DATAFLUX_RUM.getResource(resourceId)
API semantics:
createResourceTrackerId()Creates a new tracker IDsetResourceContext(resourceId, context)Overwrites the current tracker's contextappendResourceContext(resourceId, context)Appends additional fields to the current tracker's contextfinishResource(resourceId)Signals that the tracked resource is ready to complete. If the request has already finished, the resource is immediately uploaded; if not, the SDK waits until the request completes before uploadinggetResource(resourceId)Returns a snapshot of the current tracker, primarily for debugging
Fetch Example¶
const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()
window.DATAFLUX_RUM.setResourceContext(resourceId, {
order_id: '123',
scene: 'checkout'
})
fetch('/api/order/detail', {
headers: {
'x-rum-resource-id': resourceId
}
})
.then((response) => {
window.DATAFLUX_RUM.appendResourceContext(resourceId, {
result: 'success',
response_status: response.status
})
window.DATAFLUX_RUM.finishResource(resourceId)
return response
})
.catch((error) => {
window.DATAFLUX_RUM.appendResourceContext(resourceId, {
result: 'error',
error_message: error.message
})
window.DATAFLUX_RUM.finishResource(resourceId)
throw error
})
XHR Example¶
const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()
window.DATAFLUX_RUM.setResourceContext(resourceId, {
order_id: '123',
scene: 'checkout'
})
const xhr = new XMLHttpRequest()
xhr.open('GET', '/api/order/detail', true)
xhr.setRequestHeader('x-rum-resource-id', resourceId)
xhr.addEventListener('load', () => {
window.DATAFLUX_RUM.appendResourceContext(resourceId, {
result: 'success',
response_status: xhr.status
})
window.DATAFLUX_RUM.finishResource(resourceId)
})
xhr.addEventListener('error', () => {
window.DATAFLUX_RUM.appendResourceContext(resourceId, {
result: 'error',
error_message: 'xhr_error'
})
window.DATAFLUX_RUM.finishResource(resourceId)
})
xhr.send()
Trace Scenario Example¶
If the same request also needs to inject a trace ID, keep x-rum-resource-id and ensure the request URL is already configured in the tracing allowlist. The CDN example below uses the default ddtrace; to explicitly specify a different type, refer to the traceType description in the initialization parameters.
Then send the tracked request as usual:
const resourceId = window.DATAFLUX_RUM.createResourceTrackerId()
window.DATAFLUX_RUM.setResourceContext(resourceId, {
scene: 'checkout'
})
fetch('/api/order/detail', {
headers: {
'x-rum-resource-id': resourceId
}
})
.then((response) => {
window.DATAFLUX_RUM.appendResourceContext(resourceId, {
trace_expected: 'true',
response_status: response.status
})
window.DATAFLUX_RUM.finishResource(resourceId)
return response
})
The rawRumEvent._gc in the final tracker snapshot may contain traceId and spanId.
Debugging¶
You can inspect the current tracker snapshot at any time:
Typical snapshot structure:
{
trackerId: 'uuid',
status: 'request_collected',
context: {
order_id: '123',
result: 'success'
},
resource: {
type: 'fetch',
url: '/api/order/detail',
method: 'GET',
status: 200
},
rawRumEvent: {
type: 'resource',
_gc: {
traceId: '...',
spanId: '...'
}
}
}
Possible status values:
createdrequest_collectedfinishedflushedtimeout_flushedcleared
Timeout Behavior¶
If the application does not call finishResource(), the SDK automatically flushes the tracked resource after 30s.
A common misunderstanding:
- This
30sstarts counting after the request completes - Not from the start of the request
The actual timeline:
- Request starts
- Request completes
- SDK associates it with the resource via
x-rum-resource-id - If
finishResource()has not been called by then, the SDK waits at most30s - After the timeout, the resource is uploaded with status
timeout_flushed
This prevents tracked requests from remaining pending indefinitely while still giving application code a window to attach post-response context after the request finishes.
Timeline Details¶
- If
finishResource()is called before the request completes, the SDK does not upload immediately. It marks the tracker asfinishedand waits until the request actually completes to flush. - If
finishResource()is called after the request completes, the SDK flushes immediately. - If
finishResource()is never called, the SDK follows the "wait30safter request completion and then auto-flush" logic described above.
Notes¶
- Business requests must allow the custom header
x-rum-resource-id - If the request does not carry this header, it automatically falls back to normal resource collection
- If the header contains a tracker ID that does not exist, it also falls back to normal resource collection
getResource()is primarily for debugging and should not be relied upon as a business logic dependency