查询函数:通过 API 网关对外提供只读能力
Query 是函数的只读子集,可以通过 API 网关对外暴露,且不允许有副作用。这篇讲装饰器、API 名校验、版本管理与调用方式。
https://www.palantir.com/docs/foundry/functions/query-functions/
原始标题:Language-agnostic features > Publish and call query functions through API gateway
先记住这几条
写在前面
Query 装饰器
Query 装饰器
使用以下语法定义一个查询函数。
import { Query } from "@foundry/functions-api";
@Query({ apiName: "myTypeScriptV1Function" })// 在包含该函数的文件中导出一个带有 apiName 参数的配置对象
export const config = {
apiName: "myTypeScriptV2Function"
};from functions.api import function
@function(api_name="myPythonFunction")对于 Python 和 TypeScript v1 函数,装饰器接受一个 string 类型的 API 名称参数,该参数用于定义 API 名称,是必需的。使用 TypeScript v1 时,如果未定义 apiName 参数,该查询的行为将与既有的 @Function 装饰器类似。对应的 Python 语法是 api_name。
Example: API-named query
下面的示例演示如何通过 API 网关暴露一个查询:
import { Query, Double } from "@foundry/functions-api";
import { Objects, Aircraft } from "@foundry/ontology-api";
export class PublishedQueries {
@Query({ apiName: "getReschedulableAircraftCount" })
public async countAircraftTakingOffAfter(minimumTimeInMinutes: Double): Promise<Double> {
const aircraftCount = await Objects.search().aircraft()
.filter(aircraft => aircraft.timeUntilNextFlight.range().gt(minimumTimeInMinutes))
.count();
return aircraftCount!;
}
}import { Client } from "@osdk/client";
import { Double } from "@osdk/functions";
import { Aircraft } from "@ontology/sdk";
export const config = {
apiName: "getReschedulableAircraftCount"
};
async function countAircraftTakingOffAfter(client: Client, minimumTimeInMinutes: Double): Promise<Double> {
const { $count } = await client(Aircraft).where({
timeUntilNextFlight: {
$gt: minimumTimeInMinutes
}
}).aggregate({ $select: { $count: "unordered" } })
return $count;
}
export default countAircraftTakingOffAfter;
from functions.api import Double, function
from ontology_sdk import FoundryClient
from ontology_sdk.ontology.objects import Aircraft
@function(api_name="getReschedulableAircraftCount")
def count_aircraft_taking_off_after(minimum_time_in_minutes: Double) -> Double:
client = FoundryClient()
aircraft_count = client.ontology.objects.Aircraft.where(
Aircraft.object_type.time_until_next_flight > minimum_time_in_minutes
).count().compute()
return aircraft_countAPI 名校验
API 名校验
查询的 apiName 必须是一个满足以下要求的字符串:
- 采用
lowerCamelCase(小驼峰)形式。 - 长度小于 100 个字符。
- 不能以数字开头。
- 在导入到仓库的所有 Ontology 之间保持唯一。
- 如果
apiName不唯一,打标签过程会失败,需要你更改名称。
此外,包含 API 命名查询的仓库必须从至少一个 Ontology 导入实体。
版本与更新
版本与更新
API 命名的查询始终使用已发布查询的最新标签版本,并不遵循与其他 Foundry 函数相同的语义化版本(semantic versioning)范式。
要将 API 名称与查询解除关联、并在 API 网关中使其失效,必须从查询装饰器中移除 API 名称,并从仓库发布一个新的标签。
在装饰器中更改 API 名称并发布新标签,会使调用方失效。仅支持该查询最新发布的版本。
为了让调用方能够在不产生破坏性变更的情况下按需升级,你可以支持同一 API 名称的多个版本。为此,你必须在仓库中复制一份查询代码,并赋予一个不同的 API 名称,例如 getReschedulableAircraftCountV2。
搜索与查看
搜索与查看
与其他函数一样,你可以在 Ontology Manager 中搜索和管理你的查询。你可以按查询名称或 API 名称搜索。在上面的示例中,API 名称对应 getReschedulableAircraftCount,查询名称对应 countAircraftTakingOffAfter。

使用 TypeScript v1 函数时,你可能需要更新仓库中的 functions.json 文件,将 enableQueries 属性设为 true 以启用查询:<br><br>
{
"enableQueries": true
}调用 query 函数
调用 query 函数
发布你的 TypeScript 或 Python 查询函数后,导航到你想消费该函数的代码仓库,并使用 Resource imports(资源导入) 侧边栏导入它。
你的函数将可以从消费方仓库中被调用。例如:
import { Queries } from "@foundry/ontology-api";
export class MyFunctions {
@Function()
public callQueryFunction(): Promise<Double> {
return Queries.getReschedulableAircraftCount(10);
}
}import { Client } from "@osdk/client";
import { Double } from "@osdk/functions";
import { getReschedulableAircraftCount } from "@ontology/sdk";
async function callQueryFunction(client: Client): Promise<Double> {
return client(getReschedulableAircraftCount).executeFunction({ timeUntilNextFlight: 10 });
}
export default callQueryFunction;from functions.api import Double, function
from ontology_sdk import FoundryClient
@function
def call_query_function() -> Double:
return FoundryClient().ontology.queries.get_reschedulable_aircraft_count(
time_until_next_flight=Double(10)
)对于 TypeScript v1 函数,Foundry 必须知道你从已发布函数中调用了哪些查询函数和语言模型方法。我们自动提供静态分析,尝试检测出被调用的查询。但这一静态分析偶尔可能漏掉某些调用,从而导致运行时错误,提示你添加 @Uses 装饰器。该装饰器用于补全自动检测出的查询使用情况。语言模型方法也列在同一个 queries 数组中。
以下示例演示了 @Uses 装饰器的用法:
import { Uses } from "@foundry/functions-api";
import { Queries } from "@foundry/ontology-api";
export class MyFunctions {
@Uses({ queries: [Queries.getReschedulableAircraftCount] })
@Function()
public callQueryFunction(): Promise<Double> {
return Queries.getReschedulableAircraftCount(10);
}
}延伸阅读 · 相关页面
按主题横向跳转,不必顺着目录一篇篇读。
常见问题速答 · FAQ
关于「查询函数:通过 API 网关对外提供只读能力」,读者最常问的几个问题。