跳转至

TypeScript OSDK migration guide (1.x to 2.0)(TypeScript 开源软件开发工具包(TypeScript OSDK) 迁移指南(1.x 到 2.0))

This guide is intended to help you migrate applications using TypeScript OSDK 1.x to TypeScript OSDK 2.0. The sections below explain the differences between the two versions and highlights relevant changes in syntax and structure.

:::callout{theme="neutral"} TypeScript documentation is also available in-platform in the Developer Console at /workspace/developer-console/. Use the version picker to select 2.0 for documentation on TypeScript OSDK 2.0. :::

Why upgrade from TypeScript OSDK 1.x to 2.0?

Performance and scalability

TypeScript OSDK 1.x enables users to interact with the Ontology outside of the Palantir platform. However, this initial version had limited scalability:

  • TypeScript OSDK 1.x generates full implementations of code for any object, Action, or other Ontology item. This means that the OSDK 1.x scales with the size of your entire Ontology, which could be very large.
  • TypeScript OSDK 1.x closely couples the client to the generated Ontology.

TypeScript OSDK 2.0 provides a number of performance and usability improvements by overhauling the way the SDK is generated and how the Ontology is accessed.

  • TypeScript OSDK 2.0 scales linearly with the shape and metadata of your Ontology instead of the actual Ontology. This significantly improves OSDK performance since the OSDK is no longer tied to all of the items in your Ontology. TypeScript OSDK 2.0 also supports lazy loading, meaning that applications only require what they use when they use it.
  • TypeScript OSDK 2.0 separates the client from your generated code, which makes it easier to deploy rapid hotfixes by enabling quicker library dependency updates without requiring SDK regeneration. TypeScript OSDK 2.0 also exponentially increases the capability for code reuse through an OSDK codebase.
  • TypeScript OSDK 2.0 provides streamlined code generation, which can significantly increase iteration speed when building against large ontologies.

For more details on major design differences between the two versions and the rationale behind them, review the developer documentation ↗ in the open-source TypeScript OSDK repository.

Support and features

The new TypeScript version of the OSDK increases interaction capabilities to the Ontology. Because of this, new feature releases such as interfaces and media sets will require TypeScript OSDK 2.0.

:::callout{theme="warning"} Palantir will maintain support for the TypeScript version 1.x of OSDK for at least one year after the release of TypeScript OSDK 2.0. :::

How do I upgrade from TypeScript OSDK 1.x to 2.0?

You can generate a new SDK version for an existing Developer Console application using the Typescript OSDK 2.0 generator in the SDK versions tab of your application. Existing applications must also have the required dependencies to use the newly generated SDK. New applications created in Developer Console will generate SDKs using the Typescript OSDK 2.0 generator by default, and developers can quickly get started by following the instructions in the Start developing tab.

Generate a new version of your SDK with the new 2.0 version of the TypeScript OSDK.

Migrate from TypeScript OSDK 1.x to 2.0

  1. Ensure you have installed all newly required dependencies in your project.
  2. Instantiate a new TypeScript OSDK 2.0 client.
  3. Modify your project's query calls, focusing on updating the syntax of calls and tweaking the handling of return types as needed.
  4. Modify your project’s Action calls. Apart from syntax, the major change here is updating code that may be looking at validation or Action edit responses.
  5. Migrate object types.
  6. Conduct a thorough review of how OSDK object types are used within your code.
    1. Identify where you rely on the object types generated by the 1.x version of the OSDK, and understand how they differ from the types used by the 2.0 version.
    2. Decide on an optimal solution path for your codebase.
  7. Next, review your OSDK usage and modify object loads to use the new client. Follow the steps in the objects syntax translation section and note any changes in property types.
  8. Review other differences between the two versions of the OSDK.

Initial setup

Install the latest versions of the @osdk/client package from npm, or update your project’s package-lock.json accordingly.

npm install @osdk/client
npm install @osdk/oauth

Client/Auth

Creation

The client in TypeScript OSDK 2.0 is created using the createClient function. This function requires an additional parameter named ontologyRid. The ontologyRid parameter can be passed as a string, read from an environment variable, or dynamically read from the new $ontologyRid variable that is generated in your SDK package.

TypeScript OSDK 1.x (legacy)

import { FoundryClient, PublicClientAuth } from "@your-generated-sdk";

//Public OAuth
const auth = new PublicClientAuth({
        clientId: FOUNDRY_CLIENT_ID,
        url: FOUNDRY_API_URL,
        redirectUrl: APPLICATION_REDIRECT_URL,
    });

const legacyClient = new FoundryClient({
    url: API_PROXY_TARGET_URL,
    auth: auth,
});

TypeScript OSDK 2.0

import { createClient } from "@osdk/client";
import {
    PublicOauthClient,
    createConfidentialOauthClient,
    createPublicOauthClient
} from "@osdk/oauth";
import { $ontologyRid } from "@your-generated-sdk";

// Confidential OAuth
const auth = createConfidentialOauthClient(
    FOUNDRY_CLIENT_ID,
    FOUNDRY_CLIENT_SECRET,
    FOUNDRY_API_URL,
);

// Or

// Public OAuth
const auth = createPublicOauthClient(
    FOUNDRY_CLIENT_ID,
    FOUNDRY_API_URL,
    APPLICATION_REDIRECT_URL
);

const client = createClient(
    FOUNDRY_API_URL,
    $ontologyRid, // See note
    auth
);

:::callout{theme="neutral"} If you install your Ontology’s OSDK through the CLI, your $ontologyRid will be exported from the root of the SDK package, which you can access as above. Otherwise, you need to pass in your known ontologyRid to where you construct the client. You can get this information from the Ontology Manager in Foundry. Select your desired ontology, navigate to the Ontology configuration tab, and copy your Ontology RID from the Ontology metadata section. :::

Usage and general syntax

TypeScript OSDK 1.x (legacy)

In TypeScript OSDK 1.x, you can access methods on the client through a nested object structure. For example:

 legacyClient.objects.legacyObject.fetchPage();

TypeScript OSDK 2.0

In TypeScript OSDK 2.0, the client is now directly invocable. This means you can interface with the client, passing in the objects or Actions you want to work with. The new usage pattern generally follows this syntax:

client(myObject).fetchPage()
client($Objects.myObject).fetchPage()

Objects

The primary distinction between object types in TypeScript version 1.x and version 2.0 lies in the different types used to access an object's data. In the 1.x version, you could access an object's properties by interfacing with a myObject type. However, in version 2.0, similar functionality to the legacy object type is present in the wrapped type: Osdk.Instance<myObject>.

This is reflected in the method return types throughout the SDK. For example, the TypeScript OSDK 1.x page result type is Page<myObject>, whereas the TypeScript OSDK 2.0 page result type is PageResult<Osdk.Instance<myObject>>.

This creates several different compatibility problems you may face when converting your code.

Issue: Osdk.Instance<myObject> is not equivalent to legacyMyObject

There have been significant changes to the properties within two objects.

  • TypeScript OSDK 1.x uses GeoShape, GeoPoint while TypeScript OSDK 2.0 uses GeoJSON
  • TypeScript OSDK 1.x uses Timestamp, LocalDate while TypeScript OSDK 2.0 treats those types as strings

Imagine you want to replace your object load calls with the new client but do not want to change any of your helper functions that would expect object types from the legacy TypeScript OSDK 1.x. Assume that you are still importing object types from the legacy TypeScript OSDK 1.x; in this case, you will encounter errors due to the two types being incompatible.

const objectResult: Result<legacyMyObject, GetObjectError> =
    await legacyClient.ontology.
    objects.legacyMyObject.fetchOne("<primaryKey");

const object = client(myObject).fetchOne("<primaryKey>");
   -> Returns Osdk.Instance<myObjectV2>

const locationName = getObjectLocation(object)

function getLocation(obj: legacyMyObject){...} : Unmodified

This is because Osdk.Instance<myObjectV2> is not compatible with legacyMyObject.

Issue: ObjectType ≠ Osdk.Instance

In TypeScript OSDK 2.0, wrapping an object type in Osdk.Instance<> is crucial for accessing various properties. The Osdk wrapper elevates these properties to the top level of the type, making it more analogous to legacy types in TypeScript OSDK 1.x.

However, if you modify object type imports to come from TypeScript OSDK 2.0, an issue would occur. Without the Osdk wrapper, you would not have top level access to object properties, and the imports would be missing the other fields listed above.

const object = client(myObjectV2).fetchOne("<primaryKey>");
    -> returns Osdk.Instance<myObjectV2>
const locationName = getObjectLocation(object)

function getLocation(obj: myObjectV2){ ... }

This is because Osdk.Instance<myObjectV2> is not compatible with myObjectV2.

Solution paths

Consider the following ways you can edit your code to use the new OSDK object types in TypeScript OSDK 2.0:

  1. Direct replacement: Substitute all instances of the legacy object type in your codebase with the corresponding TypeScript OSDK 2.0 object type as you modify object retrievals. This is optimal for simple use cases, but challenging for codebases that heavily use TypeScript OSDK 1.x object types.
  2. Custom frontend types: Prior to migrating objects to TypeScript OSDK 2.0, refactor your code to use custom frontend types instead of the built-in legacy TypeScript OSDK 1.x types. Then, develop a translator function that maps legacy TypeScript OSDK 1.x types to your custom types. When you commence the migration to TypeScript OSDK 2.0, you will only need to update the translator function, leaving the rest of your codebase intact.

Syntax translations

This section contains simple examples that illustrate how to map between TypeScript OSDK 1.x and 2.0 clients. For more complex TypeScript OSDK 2.0 syntax examples, refer to the OSDK examples on Palantir's public GitHub repository ↗.

Load single objects

TypeScript OSDK 1.x (legacy)

const objectResult: Result<legacyObject, GetObjectError> =
    await legacyClient.ontology.objects.legacyObject.fetchOneWithErrors("<primaryKey>");

TypeScript OSDK 2.0

const objectResult: Result<Osdk.Instance<myObject>> =
    await client(myObject).fetchOneWithErrors("<primaryKey>");

:::callout{theme="neutral"} You can also use the fetchOne method to have the object returned without the result wrapper. :::

Load objects with paging

TypeScript OSDK 1.x (legacy)

const objectResult =
    await legacyClient.ontology.objects.legacyObject.fetchPage({ pageSize: 30 });

TypeScript OSDK 2.0

const objectResult = await client(myObject).fetchPage({ $pageSize: 30 });

const object = objectResult.data[0];

Load all objects

TypeScript OSDK 1.x (legacy)

const objects: legacyObject[]= [];

for await (const obj of client.ontology.objects.legacyObject.asyncIter()) {
    objects.push(obj);
}
const object = objects.value[0];

TypeScript OSDK 2.0

const objects: myObject[]= [];

for await(const obj of client(myObject).asyncIter()) {
    objects.push(obj);
}
const object = objects.value[0];

TypeScript OSDK 1.x (legacy)

const object = ...load ontology object with legacy client
const link = object.legacyObjectProperty.fetchPage({ pageSize: 100 });

TypeScript OSDK 2.0

const object = ...load ontology object with new client
const link = object.$link.myObjectProperty.fetchPage({ $pageSize: 100 });

Filtering

WHERE clauses

TypeScript OSDK 1.x (legacy)**
legacyClient.ontology.objects.legacyObject
    .where(query => query.legacyProperty.startsWith("foo"))...
TypeScript OSDK 2.0
client(myObject).where({
        myObjectProperty: { $startsWith: "foo" }
    })...

orderBy clauses

Order-by clauses are now specified within the object passed to fetchPage rather than a separate filter clause.

TypeScript OSDK 1.x (legacy)
client.ontology.objects.legacyObject
    .orderBy(sortBy => sortBy.OntologyProperty.asc())
    .fetchPageWithErrors({ pageSize: 30 });
TypeScript OSDK 2.0
client(myObject).fetchPage({
        $orderBy: { "OntologyProperty": "asc" }
        $pageSize: 30
    });

Aggregations

TypeScript OSDK 2.0 syntax allows you to pass in an argument for the ordering of your aggregations. This enables you to control the order in which results are returned when specifying a groupBy aggregation. The available options are unordered, asc (ascending), and desc (descending).

Return the count of objects

TypeScript OSDK 1.x (legacy)
const aggResults = legacyClient.ontology.objects.legacyObject.where(...).count().compute();
if (isOk(aggResults)) {
    const count: number = aggResults.value;
}
TypeScript OSDK 2.0
const aggResults = client(myObject).where(...).aggregate({
    select: { $count: "unordered" }
    })
const count: number = aggResults.$count;

Group by (groupBy)

TypeScript OSDK 1.x (legacy)
legacyClient.ontology.objects.legacyObject.where(...)
    .groupBy(legacyObject => legacyObject.imageId.exact)
    .groupBy(legacyObject => legacyObject.objectLabel.exact)
    .count().
    .compute();
TypeScript OSDK 2.0
client(myObject).where(...).aggregate({ $select: { $count: "unordered" },
    $groupBy: { imageId: "exact", objectLabel: "exact" }});

Common aggregations

TypeScript OSDK 1.x (legacy)

const aggResults = legacyClient.ontology.objects.legacyObject
    .aggregate(obj => ({
        legacyObject: obj.createdBy.approximateDistinct(),
    }))
    .compute();

//OR

const aggResults = legacyClient.ontology.objects.legacyObject
 .approximateDistinct((obj) => obj.legacyProperty)
 .count()
 .compute();

if (isOk(aggResults)) {
    const result = aggregationResults.value;
}

TypeScript OSDK 2.0

const aggregationResults = client(myObject)
    .aggregate({
        $select: { "ObjectProperty:approximateDistinct": "unordered" },
    });

const result = aggregationResults.ObjectProperty;

Actions

Simple Actions

TypeScript OSDK 2.0's syntax for applying simple Actions is very similar to the legacy TypeScript OSDK 1.x syntax: in both, you call the applyAction function.

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.actions.createObject({ ...params });

TypeScript OSDK 2.0

await client(createObject).applyAction({ ...params });

Batch Actions

Batch Actions will require a similar syntax change as with simple Actions.

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.batchActions.createObject({ ...params });

TypeScript OSDK 2.0

await client(createObject).batchApplyAction({ ...params });

Action validations and edits

If you were validating inputs or receiving ActionEdits in OSDK 1.x, you can now define these by specifying $returnEdits and $validateOnly properties in the Options object. It is not possible to return edits and validateOnly at the same time.

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.actions.`createObject`({ ...params },
    { mode: ActionExcecutionMode.VALIDATE_AND_EXECUTE,
    returnEdits: ReturnEditsMode.ALL });

// If you only want to validate
await legacyClient.ontology.actions.createObject({ ...params },
    { mode: ActionExcecutionMode.VALIDATE_ONLY });

TypeScript OSDK 2.0

// This call will throw on validation errors
await client(createObject).applyAction({ ...params }, { $returnEdits: true });

await client(createObject).applyAction({ ...params }, { $validateOnly: true });

Queries

The change between TypeScript OSDK 1.x and 2.0 query syntax is very similar to the change for Actions. In TypeScript OSDK 2.0, you can call the executeFunction object on your client after you pass in the query that you want to execute.

TypeScript OSDK 1.x (legacy)

await legacyClient.queries.legacyQuery({ ...params });

TypeScript OSDK 2.0

await client(exampleQuery).executeFunction({ ...params });

Other differences

DateTime handling

The 1.x version of the TypeScript OSDK provided custom types for handling dates and times, such as LocalDate and Timestamp. TypeScript OSDK 2.0 does not provide concrete types for DateTime. Instead, for operations in the OSDK that return and accept DateTime values we instead use raw strings in the international standard of ISO 8601 ↗.

The OSDK expects properly formatted ISO 8601 strings when using DateTime properties. For example, when filtering an object set using a where clause using a DateTime property, you must provide a properly formatted string:

client(myObject).where({
    "dateTimeProperty": {
        "$gt": "2010-10-01T00:00:00Z",
    }
});

DateTime values from various OSDK methods will also be returned in this format. For example, when loading objects a DateTime property on an object will be returned with a datetime string.

Common utilities

OntologyObject

The OntologyObject type is not present in the TypeScript OSDK V2. A contextually equivalent type is the OsdkBase type found in the @osdk/api package.

IsOntologyObject

IsOntologyObject is not present in TypeScript OSDK V2.


中文翻译

TypeScript 开源软件开发工具包(TypeScript OSDK) 迁移指南(1.x 到 2.0)

本指南旨在帮助你将使用 TypeScript OSDK 1.x 版本的应用迁移至 TypeScript OSDK 2.0 版本。下文将说明两个版本的差异,重点介绍语法和结构层面的相关变更。

:::callout{theme="neutral"} 平台内的开发者控制台(Developer Console)也提供 TypeScript 文档,访问路径为 /workspace/developer-console/。如需查看 TypeScript OSDK 2.0 的相关文档,可使用版本选择器选中 2.0 即可。 :::

为什么要从 TypeScript OSDK 1.x 升级到 2.0?

性能与可扩展性

TypeScript OSDK 1.x 允许用户在 Palantir 平台外与本体(Ontology)交互,但这一初始版本的可扩展性有限: * TypeScript OSDK 1.x 会为所有对象、操作(Action)及其他本体项生成完整的代码实现。这意味着 OSDK 1.x 的规模会随整个本体的大小变化,而本体的体量可能非常庞大。 * TypeScript OSDK 1.x 的客户端与生成的本体深度耦合。

TypeScript OSDK 2.0 通过全面重构 SDK 的生成方式和本体访问方式,实现了多项性能与易用性提升: * TypeScript OSDK 2.0 的规模与本体的结构和元数据线性相关,而非与本体实际内容挂钩。由于 OSDK 不再绑定本体中的所有项,性能得到了显著提升。TypeScript OSDK 2.0 还支持懒加载(lazy loading),也就是说应用只会在需要时加载用到的内容。 * TypeScript OSDK 2.0 将客户端与生成的代码分离,无需重新生成 SDK 即可快速更新库依赖,更便于快速部署热修复补丁。同时,TypeScript OSDK 2.0 还通过 OSDK 代码库大幅提升了代码复用能力。 * TypeScript OSDK 2.0 简化了代码生成流程,在基于大体量本体进行开发时,可显著提升迭代速度。

如需了解两个版本的核心设计差异及背后的设计逻辑,可查看开源 TypeScript OSDK 代码仓库中的开发者文档 ↗

支持与功能特性

新版 TypeScript OSDK 增强了与本体的交互能力。因此,后续发布的新功能,如接口(Interface)媒体集(Media Set)都将要求使用 TypeScript OSDK 2.0 版本。

:::callout{theme="warning"} Palantir 对 TypeScript OSDK 1.x 版本的支持至少会持续到 TypeScript OSDK 2.0 发布后一年。 :::

如何从 TypeScript OSDK 1.x 升级到 2.0?

你可以在应用的 SDK 版本 标签页中,使用 TypeScript OSDK 2.0 生成器为现有开发者控制台应用生成新版本 SDK。现有应用还需安装所需依赖才可使用新生成的 SDK。在开发者控制台中新建的应用会默认使用 TypeScript OSDK 2.0 生成器生成 SDK,开发者可按照 开始开发 标签页中的指引快速上手。

使用新版 TypeScript OSDK 2.0 生成新版本 SDK。

从 TypeScript OSDK 1.x 迁移到 2.0

  1. 确保你已在项目中安装了所有新的所需依赖
  2. 实例化新版 TypeScript OSDK 2.0 客户端
  3. 修改项目的查询(Query)调用,重点更新调用语法,按需调整返回值的处理逻辑。
  4. 修改项目的操作(Action)调用。除语法变更外,这里的主要调整是更新涉及验证或操作编辑响应的相关代码。
  5. 迁移对象类型(Object Type)
  6. 全面梳理代码中 OSDK 对象类型的使用方式。
    1. 定位你依赖 1.x 版本 OSDK 生成的对象类型的位置,明确其与 2.0 版本所用类型的差异
    2. 为你的代码库确定最优解决方案路径
  7. 接下来,梳理 OSDK 的使用情况,修改对象加载逻辑以适配新客户端。遵循对象语法转换章节中的步骤,注意属性类型的所有变更。
  8. 查看两个版本 OSDK 的其他差异

Initial setup

安装 npm 上最新版本的 @osdk/client 包,或对应更新项目的 package-lock.json 文件。

npm install @osdk/client
npm install @osdk/oauth

Client/Auth

实例创建

TypeScript OSDK 2.0 的客户端通过 createClient 函数创建。该函数需要额外传入名为 ontologyRid 的参数。ontologyRid 参数可以直接传入字符串,也可以从环境变量读取,或者动态读取 SDK 包中生成的新 $ontologyRid 变量。

TypeScript OSDK 1.x (legacy)

import { FoundryClient, PublicClientAuth } from "@your-generated-sdk";

//Public OAuth
const auth = new PublicClientAuth({
        clientId: FOUNDRY_CLIENT_ID,
        url: FOUNDRY_API_URL,
        redirectUrl: APPLICATION_REDIRECT_URL,
    });

const legacyClient = new FoundryClient({
    url: API_PROXY_TARGET_URL,
    auth: auth,
});

TypeScript OSDK 2.0

import { createClient } from "@osdk/client";
import {
    PublicOauthClient,
    createConfidentialOauthClient,
    createPublicOauthClient
} from "@osdk/oauth";
import { $ontologyRid } from "@your-generated-sdk";

// Confidential OAuth
const auth = createConfidentialOauthClient(
    FOUNDRY_CLIENT_ID,
    FOUNDRY_CLIENT_SECRET,
    FOUNDRY_API_URL,
);

// Or

// Public OAuth
const auth = createPublicOauthClient(
    FOUNDRY_CLIENT_ID,
    FOUNDRY_API_URL,
    APPLICATION_REDIRECT_URL
);

const client = createClient(
    FOUNDRY_API_URL,
    $ontologyRid, // See note
    auth
);

:::callout{theme="neutral"} 如果你通过 CLI 安装本体的 OSDK,$ontologyRid 会从 SDK 包的根目录导出,你可以按照上述方式直接引用。否则,你需要在构建客户端的位置手动传入已知的 ontologyRid。你可以在 Foundry 的本体管理器(Ontology Manager)中获取该信息:选中目标本体,进入 本体配置 标签页,从 本体元数据 板块复制本体 RID 即可。 :::

使用方式与通用语法

TypeScript OSDK 1.x (legacy)

在 TypeScript OSDK 1.x 中,你可以通过嵌套的对象结构访问客户端上的方法,示例如下:

 legacyClient.objects.legacyObject.fetchPage();

TypeScript OSDK 2.0

在 TypeScript OSDK 2.0 中,客户端可直接调用。你可以直接与客户端交互,传入你要使用的对象或操作即可。新的使用模式通常遵循以下语法:

client(myObject).fetchPage()
client($Objects.myObject).fetchPage()

Objects

TypeScript 1.x 版本和 2.0 版本中对象类型的核心差异在于访问对象数据所用的类型不同。在 1.x 版本中,你可以通过 myObject 类型访问对象的属性。而在 2.0 版本中,与旧版对象类型功能相近的是包装类型:Osdk.Instance<myObject>

这一差异体现在整个 SDK 的方法返回类型中。例如,TypeScript OSDK 1.x 的分页结果类型是 Page<myObject>,而 TypeScript OSDK 2.0 的分页结果类型是 PageResult<Osdk.Instance<myObject>>

这会导致你转换代码时可能遇到多种兼容性问题。

问题:Osdk.Instance<myObject>legacyMyObject 不兼容

两个对象内部的属性有大幅变更: * TypeScript OSDK 1.x 使用 GeoShape, GeoPoint 类型,而 TypeScript OSDK 2.0 使用 GeoJSON 类型 * TypeScript OSDK 1.x 使用 Timestamp, LocalDate 类型,而 TypeScript OSDK 2.0 将这些类型处理为 strings 类型

假设你要把对象加载调用替换为新客户端的实现,但不想修改任何期望接收旧版 TypeScript OSDK 1.x 对象类型的辅助函数。如果你仍然从旧版 TypeScript OSDK 1.x 中导入对象类型,此时会因为两个类型不兼容而报错。

const objectResult: Result<legacyMyObject, GetObjectError> =
    await legacyClient.ontology.
    objects.legacyMyObject.fetchOne("<primaryKey");

const object = client(myObject).fetchOne("<primaryKey>");
   -> Returns Osdk.Instance<myObjectV2>

const locationName = getObjectLocation(object)

function getLocation(obj: legacyMyObject){...} : Unmodified
出现该问题的原因是 Osdk.Instance<myObjectV2>legacyMyObject 不兼容。

问题:ObjectType ≠ Osdk.Instance

在 TypeScript OSDK 2.0 中,将对象类型包装在 Osdk.Instance<> 中是访问各类属性的必要前提。Osdk 包装器会将这些属性提升到类型的顶层,使其更接近 TypeScript OSDK 1.x 中的旧版类型。

但如果你将对象类型的导入来源改为 TypeScript OSDK 2.0,就会遇到问题:如果没有 Osdk 包装器,你无法在顶层访问对象属性,导入内容也会缺失上述其他字段。

const object = client(myObjectV2).fetchOne("<primaryKey>");
    -> returns Osdk.Instance<myObjectV2>
const locationName = getObjectLocation(object)

function getLocation(obj: myObjectV2){ ... }
出现该问题的原因是 Osdk.Instance<myObjectV2>myObjectV2 不兼容。

Solution paths

你可以参考以下方式修改代码,适配 TypeScript OSDK 2.0 中的新 OSDK 对象类型: 1. 直接替换:修改对象获取逻辑的同时,将代码库中所有旧版对象类型的实例替换为对应的 TypeScript OSDK 2.0 对象类型。该方案适合简单的使用场景,但对于大量使用 TypeScript OSDK 1.x 对象类型的代码库来说难度较高。 2. 自定义前端类型:在将对象迁移到 TypeScript OSDK 2.0 之前,重构代码使用自定义前端类型,替代内置的旧版 TypeScript OSDK 1.x 类型。然后开发一个转换函数,将旧版 TypeScript OSDK 1.x 类型映射到你的自定义类型。当你开始迁移到 TypeScript OSDK 2.0 时,只需要更新转换函数即可,代码库的其余部分无需改动。

Syntax translations

本章节通过简单示例说明 TypeScript OSDK 1.x 和 2.0 客户端的用法映射关系。如需查看更复杂的 TypeScript OSDK 2.0 语法示例,可参考Palantir 公开 GitHub 仓库中的 OSDK 示例 ↗

加载单个对象

TypeScript OSDK 1.x (legacy)

const objectResult: Result<legacyObject, GetObjectError> =
    await legacyClient.ontology.objects.legacyObject.fetchOneWithErrors("<primaryKey>");

TypeScript OSDK 2.0

const objectResult: Result<Osdk.Instance<myObject>> =
    await client(myObject).fetchOneWithErrors("<primaryKey>");

:::callout{theme="neutral"} 你也可以使用 fetchOne 方法直接返回对象,无需结果包装。 :::

分页加载对象

TypeScript OSDK 1.x (legacy)

const objectResult =
    await legacyClient.ontology.objects.legacyObject.fetchPage({ pageSize: 30 });

TypeScript OSDK 2.0

const objectResult = await client(myObject).fetchPage({ $pageSize: 30 });

const object = objectResult.data[0];

加载所有对象

TypeScript OSDK 1.x (legacy)

const objects: legacyObject[]= [];

for await (const obj of client.ontology.objects.legacyObject.asyncIter()) {
    objects.push(obj);
}
const object = objects.value[0];

TypeScript OSDK 2.0

const objects: myObject[]= [];

for await(const obj of client(myObject).asyncIter()) {
    objects.push(obj);
}
const object = objects.value[0];

TypeScript OSDK 1.x (legacy)

const object = ...load ontology object with legacy client
const link = object.legacyObjectProperty.fetchPage({ pageSize: 100 });

TypeScript OSDK 2.0

const object = ...load ontology object with new client
const link = object.$link.myObjectProperty.fetchPage({ $pageSize: 100 });

筛选

WHERE 子句

TypeScript OSDK 1.x (legacy)**
legacyClient.ontology.objects.legacyObject
    .where(query => query.legacyProperty.startsWith("foo"))...
TypeScript OSDK 2.0
client(myObject).where({
        myObjectProperty: { $startsWith: "foo" }
    })...

orderBy 子句

排序子句现在需要在传入 fetchPage 的对象中指定,而非独立的筛选子句。

TypeScript OSDK 1.x (legacy)
client.ontology.objects.legacyObject
    .orderBy(sortBy => sortBy.OntologyProperty.asc())
    .fetchPageWithErrors({ pageSize: 30 });
TypeScript OSDK 2.0
client(myObject).fetchPage({
        $orderBy: { "OntologyProperty": "asc" }
        $pageSize: 30
    });

Aggregations

TypeScript OSDK 2.0 的语法支持传入参数指定聚合结果的排序方式。这样你可以在指定 groupBy 聚合时控制结果的返回顺序,可选值为 unordered(不排序)、asc(升序)和 desc(降序)。

返回对象计数

TypeScript OSDK 1.x (legacy)
const aggResults = legacyClient.ontology.objects.legacyObject.where(...).count().compute();
if (isOk(aggResults)) {
    const count: number = aggResults.value;
}
TypeScript OSDK 2.0
const aggResults = client(myObject).where(...).aggregate({
    select: { $count: "unordered" }
    })
const count: number = aggResults.$count;

分组(groupBy

TypeScript OSDK 1.x (legacy)
legacyClient.ontology.objects.legacyObject.where(...)
    .groupBy(legacyObject => legacyObject.imageId.exact)
    .groupBy(legacyObject => legacyObject.objectLabel.exact)
    .count().
    .compute();
TypeScript OSDK 2.0
client(myObject).where(...).aggregate({ $select: { $count: "unordered" },
    $groupBy: { imageId: "exact", objectLabel: "exact" }});

常用聚合操作

TypeScript OSDK 1.x (legacy)

const aggResults = legacyClient.ontology.objects.legacyObject
    .aggregate(obj => ({
        legacyObject: obj.createdBy.approximateDistinct(),
    }))
    .compute();

//OR

const aggResults = legacyClient.ontology.objects.legacyObject
 .approximateDistinct((obj) => obj.legacyProperty)
 .count()
 .compute();

if (isOk(aggResults)) {
    const result = aggregationResults.value;
}

TypeScript OSDK 2.0

const aggregationResults = client(myObject)
    .aggregate({
        $select: { "ObjectProperty:approximateDistinct": "unordered" },
    });

const result = aggregationResults.ObjectProperty;

Actions

简单操作

TypeScript OSDK 2.0 中执行简单操作的语法与旧版 TypeScript OSDK 1.x 非常相似:二者都调用 applyAction 函数。

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.actions.createObject({ ...params });

TypeScript OSDK 2.0

await client(createObject).applyAction({ ...params });

批量操作

批量操作的语法变更与简单操作类似。

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.batchActions.createObject({ ...params });

TypeScript OSDK 2.0

await client(createObject).batchApplyAction({ ...params });

操作验证与编辑

如果你在 OSDK 1.x 中会进行输入验证或者接收 ActionEdits,现在可以通过在 Options 对象中指定 $returnEdits$validateOnly 属性来实现。注意无法同时开启返回编辑和仅验证模式。

TypeScript OSDK 1.x (legacy)

await legacyClient.ontology.actions.`createObject`({ ...params },
    { mode: ActionExcecutionMode.VALIDATE_AND_EXECUTE,
    returnEdits: ReturnEditsMode.ALL });

// If you only want to validate
await legacyClient.ontology.actions.createObject({ ...params },
    { mode: ActionExcecutionMode.VALIDATE_ONLY });

TypeScript OSDK 2.0

// This call will throw on validation errors
await client(createObject).applyAction({ ...params }, { $returnEdits: true });

await client(createObject).applyAction({ ...params }, { $validateOnly: true });

Queries

TypeScript OSDK 1.x 和 2.0 的查询语法变更与操作的变更非常相似。在 TypeScript OSDK 2.0 中,你需要先传入要执行的查询,然后调用客户端上的 executeFunction 对象即可。

TypeScript OSDK 1.x (legacy)

await legacyClient.queries.legacyQuery({ ...params });

TypeScript OSDK 2.0

await client(exampleQuery).executeFunction({ ...params });

其他差异

DateTime 处理

TypeScript OSDK 1.x 版本提供了自定义类型处理日期和时间,比如 LocalDateTimestamp。TypeScript OSDK 2.0 没有为 DateTime 提供具体类型,OSDK 中返回和接收 DateTime 值的操作都采用遵循ISO 8601 ↗国际标准的原始字符串。

使用 DateTime 属性时,OSDK 要求传入格式正确的 ISO 8601 字符串。例如,使用 DateTime 属性在 where 子句中筛选对象集时,你必须提供格式正确的字符串:

client(myObject).where({
    "dateTimeProperty": {
        "$gt": "2010-10-01T00:00:00Z",
    }
});
各类 OSDK 方法返回的 DateTime 值也会采用该格式。例如,加载对象时,对象上的 DateTime 属性会返回日期时间字符串。

通用工具

OntologyObject

TypeScript OSDK V2 中不存在 OntologyObject 类型,功能对等的类型是 @osdk/api 包中的 OsdkBase 类型。

IsOntologyObject

TypeScript OSDK V2 中不存在 IsOntologyObject 类型。