Hello Palantir Community,
We’re developing a custom widget in Palantir Foundry using the @osdk/client
TypeScript SDK to enhance our application’s functionality. Our goal is to dynamically retrieve the Resource IDs (RIDs) for specific object instances based on their primary keys to construct navigation URLs within a workshop module. However, we’re facing difficulties accessing the RID from the objects fetched via the SDK, and we’d appreciate your guidance.
What We’re Trying to Do
-
Objective: For each record in our dataset, we need to fetch related object instances using their primary keys and extract their RIDs (e.g., a format like
ri.phonograph2-objects.main.object.<uuid>
) to build a URL for navigation, such as:https://<foundry-domain>/workspace/<workspace-id>/<module-id>?param.page=<page>&m.variable.selected-object1=<object1Rid>&m.variable.selected-object2=<object2Rid>
-
Current Workflow:
- Fetch an initial object using a unique identifier to retrieve a related primary key.
- Use
client(<ObjectType1>).where({ primaryKey: { $eq: relatedKey } })
to get the first related object instance. - Use
client(<ObjectType2>).where({ primaryKey: { $eq: record.primaryKey } })
to get the second related object instance. - Extract the RID from these instances to construct the URL.
-
Challenge: The
Osdk.Instance
objects returned byfetchPageWithErrors
orfetchOne
do not expose therid
property directly (e.g.,instance.rid
is undefined). Logging the object properties withJSON.stringify
doesn’t reveal the RID either.
Code Snippets
Current Implementation
Here’s a generalized version of our code where we attempt to fetch objects and construct the URL:
const handleNavigationClick = async (record: any) => {
if (!record.identifier || !record.relatedKey) {
console.warn("Identifier or related key missing for record:", record);
return;
}
try {
// Step 1: Fetch initial object using the identifier
const initialResponse: Result<PageResult<Osdk.Instance<any>>> =
await client(InitialObject)
.where({ identifier: { $eq: record.identifier } })
.fetchPageWithErrors({ $pageSize: 1 });
if (!isOk(initialResponse) || initialResponse.value.data.length === 0) {
console.error("No initial object found for identifier:", record.identifier);
return;
}
const initialObject = initialResponse.value.data[0];
const relatedKey = initialObject.relatedKey;
if (!relatedKey) {
console.error("No related key found in initial object for identifier:", record.identifier);
return;
}
// Step 2: Fetch first related object
const object1ObjectSet = client(ObjectType1).where({ primaryKey: { $eq: relatedKey } });
const object1Response = await object1ObjectSet.fetchPageWithErrors({ $pageSize: 1 });
if (!isOk(object1Response) || object1Response.value.data.length === 0) {
console.error("No ObjectType1 found for related key:", relatedKey);
return;
}
const object1 = object1Response.value.data[0];
console.log("ObjectType1 properties:", JSON.stringify(object1, null, 2)); // RID not found
// Step 3: Fetch second related object
const object2ObjectSet = client(ObjectType2).where({ primaryKey: { $eq: record.relatedKey } });
const object2Response = await object2ObjectSet.fetchPageWithErrors({ $pageSize: 1 });
if (!isOk(object2Response) || object2Response.value.data.length === 0) {
console.error("No ObjectType2 found for primary key:", record.relatedKey);
return;
}
const object2 = object2Response.value.data[0];
console.log("ObjectType2 properties:", JSON.stringify(object2, null, 2)); // RID not found
// Step 4: Use placeholder RIDs for now (as a fallback)
const object1Rid = "ri.phonograph2-objects.main.object.<placeholder-uuid>";
const object2Rid = "ri.phonograph2-objects.main.object.<placeholder-uuid>";
// Step 5: Construct the URL
const param1 = `m.variable.selected-object1=${object1Rid}`;
const param2 = `m.variable.selected-object2=${object2Rid}`;
const navigationUrl = `${BASE_URL}${PAGE_PARAM}&${param1}&${param2}`;
console.log("Navigating to URL:", navigationUrl);
window.open(navigationUrl, "_blank");
} catch (error) {
console.error("Error constructing navigation URL:", error);
}
};
- Observation: The
JSON.stringify
output does not contain arid
field, and we’re unsure how to access it directly.
Alternative Attempt with fetchOne
We also tried using fetchOne
to see if it provides the RID:
const object1Response: Result<Osdk.Instance<any>> = await client(ObjectType1).fetchOne(relatedKey);
if (isOk(object1Response)) {
const object1 = object1Response.value;
console.log("ObjectType1 with fetchOne:", JSON.stringify(object1, null, 2)); // Still no rid
const object1Rid = object1.rid; // Undefined
} else {
console.error("Failed to fetch ObjectType1:", object1Response.error);
}
- Result: The
rid
property remains undefined, and the object properties don’t include it.
Questions and Request for Help
-
How can we retrieve the RID of an individual object instance using the @osdk/client SDK?
- Is there a specific method (e.g.,
getRid()
,fetchRid()
) or property we’re missing? - Should we be using a different API endpoint (e.g.,
/v1/ontologies/{ontologyRid}/objects/{objectType}/{primaryKey}
) wrapped by the SDK?
- Is there a specific method (e.g.,
-
Workaround Suggestions:
- If the RID isn’t exposed in the
Osdk.Instance
, is there a recommended way to query it via the SDK or a raw API call? - We’ve considered using the
OntologyObject.get
endpoint (as per the Foundry API docs), but we’re unsure how to integrate it with the SDK.
- If the RID isn’t exposed in the
-
Debugging Tips:
- Are there additional logs or tools we can use to inspect the full object metadata, including the RID?
Additional Context
- We’re using the
@osdk/client
SDK within a TypeScript environment, integrated with our custom application. - The current workaround uses placeholder RIDs, which works temporarily but isn’t scalable.
Any guidance, code examples, or pointers to documentation would be greatly appreciated! Thank you in advance for your support.