@microsoft/rayfin-guide 1.36.0-alpha.1593 → 1.36.0-alpha.1620
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/docs/{experimental/cli → cli}/connectors/add.md +2 -0
- package/assets/docs/{experimental/cli → cli}/connectors/category-a-entities.md +1 -1
- package/assets/docs/{experimental/cli → cli}/connectors/category-b-function-bridge.md +38 -12
- package/assets/docs/cli/connectors/eventhouse.md +21 -0
- package/assets/docs/{experimental/cli → cli}/connectors/index.md +7 -22
- package/assets/docs/{experimental/cli → cli}/connectors/invoke.md +4 -0
- package/assets/docs/{experimental/cli → cli}/connectors/search.md +4 -2
- package/assets/docs/cli/environment-variables.md +2 -2
- package/assets/docs/cli/functions/deploy.md +38 -0
- package/assets/docs/cli/functions/dev-apply.md +62 -0
- package/assets/docs/cli/functions/index.md +41 -0
- package/assets/docs/cli/functions/init.md +62 -0
- package/assets/docs/cli/index.md +35 -1
- package/assets/docs/cli/secrets.md +97 -122
- package/assets/docs/cli/templates.md +7 -0
- package/assets/docs/functions/connections/add-ado.md +39 -0
- package/assets/docs/functions/connections/add-azure-resource.md +171 -0
- package/assets/docs/functions/connections/add-fabric-resource.md +186 -0
- package/assets/docs/functions/connections/add-foundry.md +46 -0
- package/assets/docs/functions/connections/add-work-iq.md +39 -0
- package/assets/docs/functions/connections/get-fabric-info.md +159 -0
- package/assets/docs/functions/connections/index.md +89 -0
- package/assets/docs/functions/index.md +91 -0
- package/assets/docs/functions/invoking-from-frontend.md +94 -0
- package/assets/docs/functions/secrets.md +70 -0
- package/assets/docs/functions/typegen.md +44 -0
- package/assets/docs/functions/writing-functions.md +140 -0
- package/assets/docs/getting-started/project-structure.md +91 -2
- package/package.json +1 -1
- /package/assets/docs/{experimental/cli → cli}/connectors/inspect.md +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 2
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add a Fabric resource
|
|
6
|
+
|
|
7
|
+
Connect a function to a **Microsoft Fabric item** — a Lakehouse, Warehouse, SQL Database, OneLake files, or an Eventhouse (KQL) — and call it **as the signed-in user**.
|
|
8
|
+
|
|
9
|
+
**Before you start:** you need the item's coordinates (SQL endpoint, OneLake path, or Kusto query URI). See [Get Fabric info](./get-fabric-info.md) for how to pull them from the Fabric REST API.
|
|
10
|
+
|
|
11
|
+
All the patterns below follow the same model: declare the connection, read the token with `ctx.getToken()`, use it. See [Connecting to external resources](./index.md) for the shared model and the [`ContextTokenCredential`](./index.md#wrapping-the-token-for-azure-sdk-clients) helper referenced here.
|
|
12
|
+
|
|
13
|
+
## SQL databases
|
|
14
|
+
|
|
15
|
+
Covers Fabric **Lakehouse** (SQL analytics endpoint), **Warehouse**, **SQL Database**, and **Mirrored Database**, using `AudienceType.Sql`. The same `AudienceType.Sql` connection also works for **Azure SQL Database** — use the Azure SQL server FQDN as `server` and the database name as `database` (no item GUID).
|
|
16
|
+
|
|
17
|
+
- **Package:** `mssql@^12.6.0` (which pulls `tedious >= 19.2.2`). Older `tedious` (`<= 19.1.2`) has a LOGIN7 FeatureExt bug that causes "socket hang up" errors against Fabric endpoints.
|
|
18
|
+
- **Encryption:** `encrypt: true` (not `'strict'`). This matches ODBC `Encrypt=yes`.
|
|
19
|
+
- **Auth:** `azure-active-directory-access-token` with the token from `ctx.getToken(AudienceType.Sql)`.
|
|
20
|
+
|
|
21
|
+
Install the driver in the functions project:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd rayfin/functions
|
|
25
|
+
npm install mssql@^12.6.0
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| Resource | What to pass as `server` | What to pass as `database` |
|
|
29
|
+
| ---------------------- | ---------------------------------------- | ------------------------------------------ |
|
|
30
|
+
| **Lakehouse** | `sqlEndpointProperties.connectionString` | Item GUID (Initial Catalog — **required**) |
|
|
31
|
+
| **Warehouse** | `properties.connectionString` | Item GUID |
|
|
32
|
+
| **SQL Database** | `properties.serverFqdn` | `properties.databaseName` |
|
|
33
|
+
| **Mirrored Database** | SQL analytics endpoint | Item GUID |
|
|
34
|
+
| **Azure SQL Database** | Azure SQL server FQDN | Database name (no item GUID) |
|
|
35
|
+
|
|
36
|
+
> **Important:** For Lakehouse, Warehouse, and Mirrored Database you **must** pass the item GUID as `database`. Without it, multi-item workspaces cannot route the query correctly. Get these values via [Get Fabric info](./get-fabric-info.md).
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import {
|
|
40
|
+
UserDataFunctions,
|
|
41
|
+
AudienceType,
|
|
42
|
+
type RayfinContext,
|
|
43
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
44
|
+
import sql from "mssql";
|
|
45
|
+
|
|
46
|
+
const udf = new UserDataFunctions();
|
|
47
|
+
|
|
48
|
+
// Read these from the Fabric item — see "Get Fabric info".
|
|
49
|
+
const SQL_SERVER = "<endpoint>.datawarehouse.fabric.microsoft.com";
|
|
50
|
+
const DATABASE = "<item-guid-or-db-name>";
|
|
51
|
+
|
|
52
|
+
udf.func(
|
|
53
|
+
"queryData",
|
|
54
|
+
async (
|
|
55
|
+
ctx: RayfinContext,
|
|
56
|
+
query: string,
|
|
57
|
+
): Promise<Record<string, unknown>[]> => {
|
|
58
|
+
const token = ctx.getToken(AudienceType.Sql);
|
|
59
|
+
const pool = await sql.connect({
|
|
60
|
+
server: SQL_SERVER,
|
|
61
|
+
database: DATABASE,
|
|
62
|
+
options: { encrypt: true, trustServerCertificate: false },
|
|
63
|
+
authentication: {
|
|
64
|
+
type: "azure-active-directory-access-token",
|
|
65
|
+
options: { token },
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const result = await pool.request().query(query);
|
|
69
|
+
await pool.close();
|
|
70
|
+
return result.recordset;
|
|
71
|
+
},
|
|
72
|
+
[udf.connection({ audienceType: AudienceType.Sql })],
|
|
73
|
+
);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## OneLake files
|
|
77
|
+
|
|
78
|
+
Read and write files in a Lakehouse's OneLake storage using `AudienceType.Storage`.
|
|
79
|
+
|
|
80
|
+
The OneLake DFS URL has the form `https://onelake.dfs.fabric.microsoft.com/<workspaceId>/<itemId>/Files/<path>` — get it from `oneLakeFilesPath` via [Get Fabric info](./get-fabric-info.md#lakehouse), or construct it from the workspace and item GUIDs.
|
|
81
|
+
|
|
82
|
+
Call the DFS endpoint directly with the delegated token — no SDK required:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import {
|
|
86
|
+
UserDataFunctions,
|
|
87
|
+
AudienceType,
|
|
88
|
+
type RayfinContext,
|
|
89
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
90
|
+
|
|
91
|
+
const udf = new UserDataFunctions();
|
|
92
|
+
|
|
93
|
+
udf.func(
|
|
94
|
+
"readFile",
|
|
95
|
+
async (ctx: RayfinContext, fileUrl: string): Promise<string> => {
|
|
96
|
+
const token = ctx.getToken(AudienceType.Storage);
|
|
97
|
+
const res = await fetch(fileUrl, {
|
|
98
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
99
|
+
});
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
throw new Error(`OneLake read failed: ${res.status}`);
|
|
102
|
+
}
|
|
103
|
+
return await res.text();
|
|
104
|
+
},
|
|
105
|
+
[udf.connection({ audienceType: AudienceType.Storage })],
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Eventhouse and KQL
|
|
110
|
+
|
|
111
|
+
Query a Fabric **Eventhouse** (KQL database) or a standalone Azure Data Explorer cluster using `AudienceType.Kusto`.
|
|
112
|
+
|
|
113
|
+
Get the cluster's **query URI** from the Eventhouse's `properties.queryServiceUri` — see [Get Fabric info → Eventhouse](./get-fabric-info.md#eventhouse).
|
|
114
|
+
|
|
115
|
+
`azure-kusto-data` accepts a token provider, so hand it a callback that returns `ctx.getToken`:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import {
|
|
119
|
+
UserDataFunctions,
|
|
120
|
+
AudienceType,
|
|
121
|
+
type RayfinContext,
|
|
122
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
123
|
+
import { Client, KustoConnectionStringBuilder } from "azure-kusto-data";
|
|
124
|
+
|
|
125
|
+
const udf = new UserDataFunctions();
|
|
126
|
+
|
|
127
|
+
// Read these from the Eventhouse item — see "Get Fabric info".
|
|
128
|
+
const CLUSTER_URI = "https://<cluster>.z5.kusto.fabric.microsoft.com";
|
|
129
|
+
const DATABASE = "<kql-database-name>";
|
|
130
|
+
|
|
131
|
+
udf.func(
|
|
132
|
+
"queryKusto",
|
|
133
|
+
async (ctx: RayfinContext, query: string): Promise<unknown[]> => {
|
|
134
|
+
const kcsb = KustoConnectionStringBuilder.withTokenProvider(
|
|
135
|
+
CLUSTER_URI,
|
|
136
|
+
async () => ctx.getToken(AudienceType.Kusto),
|
|
137
|
+
);
|
|
138
|
+
const client = new Client(kcsb);
|
|
139
|
+
const response = await client.execute(DATABASE, query);
|
|
140
|
+
return response.primaryResults[0].toJSON().data;
|
|
141
|
+
},
|
|
142
|
+
[udf.connection({ audienceType: AudienceType.Kusto })],
|
|
143
|
+
);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Install the SDK in the functions project:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cd rayfin/functions
|
|
150
|
+
npm install azure-kusto-data
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Fabric REST API
|
|
154
|
+
|
|
155
|
+
Call the [Fabric REST API](https://learn.microsoft.com/en-us/rest/api/fabric/) as the calling user — for example to list items or read item metadata from inside a function — using `AudienceType.Fabric`.
|
|
156
|
+
|
|
157
|
+
The API base is fixed at `https://api.fabric.microsoft.com/v1`; `ctx.getToken(AudienceType.Fabric)` returns a token scoped for it. Send it as a bearer token with `fetch`:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import {
|
|
161
|
+
UserDataFunctions,
|
|
162
|
+
AudienceType,
|
|
163
|
+
type RayfinContext,
|
|
164
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
165
|
+
|
|
166
|
+
const udf = new UserDataFunctions();
|
|
167
|
+
|
|
168
|
+
const FABRIC_API = "https://api.fabric.microsoft.com/v1";
|
|
169
|
+
|
|
170
|
+
udf.func(
|
|
171
|
+
"listWorkspaceItems",
|
|
172
|
+
async (ctx: RayfinContext, workspaceId: string): Promise<unknown> => {
|
|
173
|
+
const token = ctx.getToken(AudienceType.Fabric);
|
|
174
|
+
const res = await fetch(`${FABRIC_API}/workspaces/${workspaceId}/items`, {
|
|
175
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
176
|
+
});
|
|
177
|
+
if (!res.ok) {
|
|
178
|
+
throw new Error(`Fabric API returned ${res.status}`);
|
|
179
|
+
}
|
|
180
|
+
return res.json();
|
|
181
|
+
},
|
|
182
|
+
[udf.connection({ audienceType: AudienceType.Fabric })],
|
|
183
|
+
);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
> This is the same API used in [Get Fabric info](./get-fabric-info.md) — the difference is that there you call it at **authoring time** (with an `az` token) to gather endpoints, whereas here the **function** calls it at runtime with the user's delegated token.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 4
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add Azure AI Foundry
|
|
6
|
+
|
|
7
|
+
Call an **Azure AI Foundry** (Azure OpenAI / Azure AI) resource from a function **as the signed-in user**, using `AudienceType.AzureAI`.
|
|
8
|
+
|
|
9
|
+
Provide the resource **endpoint** (Azure AI Foundry → your resource → _Endpoint_). The token is a standard bearer token — send it with `fetch`, or wrap it with the [`ContextTokenCredential`](./index.md#wrapping-the-token-for-azure-sdk-clients) helper for an Azure AI SDK client.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
UserDataFunctions,
|
|
14
|
+
AudienceType,
|
|
15
|
+
type RayfinContext,
|
|
16
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
17
|
+
|
|
18
|
+
const udf = new UserDataFunctions();
|
|
19
|
+
|
|
20
|
+
// Use your resource's real endpoint.
|
|
21
|
+
const AI_ENDPOINT = "https://<resource>.services.ai.azure.com";
|
|
22
|
+
|
|
23
|
+
udf.func(
|
|
24
|
+
"callAzureAi",
|
|
25
|
+
async (ctx: RayfinContext, prompt: string): Promise<unknown> => {
|
|
26
|
+
const token = ctx.getToken(AudienceType.AzureAI);
|
|
27
|
+
const res = await fetch(`${AI_ENDPOINT}/...`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: `Bearer ${token}`,
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
},
|
|
33
|
+
body: JSON.stringify({ prompt }),
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
throw new Error(`Azure AI returned ${res.status}`);
|
|
37
|
+
}
|
|
38
|
+
return res.json();
|
|
39
|
+
},
|
|
40
|
+
[udf.connection({ audienceType: AudienceType.AzureAI })],
|
|
41
|
+
);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Fill in the request path and body from the specific Azure AI API you are calling.
|
|
45
|
+
|
|
46
|
+
See [Connecting to external resources](./index.md) for the shared connection model.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 6
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Add WorkIQ
|
|
6
|
+
|
|
7
|
+
Call the **WorkIQ** service from a function **as the signed-in user**, using `AudienceType.WorkIQ`.
|
|
8
|
+
|
|
9
|
+
Provide the **WorkIQ endpoint** you are calling. The token is a standard bearer token — send it with `fetch`:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
UserDataFunctions,
|
|
14
|
+
AudienceType,
|
|
15
|
+
type RayfinContext,
|
|
16
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
17
|
+
|
|
18
|
+
const udf = new UserDataFunctions();
|
|
19
|
+
|
|
20
|
+
// Use your real WorkIQ endpoint.
|
|
21
|
+
const WORKIQ_ENDPOINT = "https://workiq.svc.cloud.microsoft/...";
|
|
22
|
+
|
|
23
|
+
udf.func(
|
|
24
|
+
"callWorkIq",
|
|
25
|
+
async (ctx: RayfinContext): Promise<unknown> => {
|
|
26
|
+
const token = ctx.getToken(AudienceType.WorkIQ);
|
|
27
|
+
const res = await fetch(WORKIQ_ENDPOINT, {
|
|
28
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
throw new Error(`WorkIQ returned ${res.status}`);
|
|
32
|
+
}
|
|
33
|
+
return res.json();
|
|
34
|
+
},
|
|
35
|
+
[udf.connection({ audienceType: AudienceType.WorkIQ })],
|
|
36
|
+
);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
See [Connecting to external resources](./index.md) for the shared connection model.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 1
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Finding resource coordinates
|
|
6
|
+
|
|
7
|
+
Every connection recipe needs a real endpoint — the SQL server, the OneLake path, the Key Vault URI, the Kusto query URI, and so on.
|
|
8
|
+
This page explains **how to obtain those values from a Fabric item** so you (or an agent authoring a function) can fill them in with real data instead of guessing.
|
|
9
|
+
|
|
10
|
+
**You only need the workspace and item _display names_ to start** — for example, "lakehouseA in workspaceB". Everything else (the workspace ID, item ID, SQL endpoint, OneLake path, Kusto URI) is derivable from here. Resolve those values rather than asking for anything you can look up.
|
|
11
|
+
|
|
12
|
+
> **Why this matters:** don't hardcode a guessed endpoint. `ctx.getToken()` gives you an access token, but you still have to point the SDK at the correct URL — and that URL comes from the Fabric item's metadata, not from `process.env`.
|
|
13
|
+
|
|
14
|
+
## Ways to get coordinates
|
|
15
|
+
|
|
16
|
+
| Source | Best for | Notes |
|
|
17
|
+
| --------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
18
|
+
| **Fabric CLI** (e.g. `fab`) | Anyone who already has a Fabric CLI installed | Wraps the REST API below. If you're already using a Fabric CLI, reach for it first. |
|
|
19
|
+
| **Fabric MCP server** | Agents running in an MCP-enabled environment | If a Fabric MCP is configured, its tools wrap the same REST endpoints below. |
|
|
20
|
+
| **Fabric REST API** | Automation, agents, reproducible lookups; no extra tooling | Canonical source. Returns endpoints/paths directly. Covered below. |
|
|
21
|
+
| **Fabric portal** | One-off manual lookups | Open the item → **Settings** / **Connection strings** and copy the value. |
|
|
22
|
+
|
|
23
|
+
If a Fabric CLI or MCP tool is already available, prefer it — it wraps the same REST endpoints. Otherwise call the REST API directly; the portal is the fallback for a quick manual copy. The rest of this page uses the REST API, since that is the source of truth every other option wraps.
|
|
24
|
+
|
|
25
|
+
## Calling the Fabric REST API
|
|
26
|
+
|
|
27
|
+
- **Base URL:** `https://api.fabric.microsoft.com/v1`
|
|
28
|
+
- **Token scope:** `https://api.fabric.microsoft.com/.default`
|
|
29
|
+
- **Auth header:** `Authorization: Bearer <token>`
|
|
30
|
+
|
|
31
|
+
Get a token at authoring time with the Azure CLI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
az account get-access-token \
|
|
35
|
+
--resource https://api.fabric.microsoft.com \
|
|
36
|
+
--query accessToken -o tsv
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> This is an **authoring-time** lookup — you are gathering coordinates to write into the function. At **runtime** the function itself uses `ctx.getToken(AudienceType.X)` (or, for the Fabric API specifically, `ctx.getToken(AudienceType.Fabric)` — see [Add a Fabric resource → Fabric REST API](./add-fabric-resource.md#fabric-rest-api)).
|
|
40
|
+
|
|
41
|
+
## Step 1 — find the workspace and item ID
|
|
42
|
+
|
|
43
|
+
List workspaces you can access:
|
|
44
|
+
|
|
45
|
+
```http
|
|
46
|
+
GET https://api.fabric.microsoft.com/v1/workspaces
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
List items of a given type in a workspace (to resolve a display name to its ID):
|
|
50
|
+
|
|
51
|
+
```http
|
|
52
|
+
GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/items?type=Lakehouse
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`type` accepts any Fabric item type — `Lakehouse`, `Warehouse`, `SQLDatabase`, `Eventhouse`, `KQLDatabase`, and so on.
|
|
56
|
+
Each entry returns `id`, `displayName`, and `type`. Take the `id` of the item you want.
|
|
57
|
+
|
|
58
|
+
## Step 2 — GET the item to read its coordinates
|
|
59
|
+
|
|
60
|
+
Each item type has a typed endpoint that returns the connection coordinates in its `properties` object.
|
|
61
|
+
|
|
62
|
+
### Lakehouse
|
|
63
|
+
|
|
64
|
+
```http
|
|
65
|
+
GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/lakehouses/{lakehouseId}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"id": "5b218778-e7a5-4d73-8187-f10824047715",
|
|
71
|
+
"type": "Lakehouse",
|
|
72
|
+
"properties": {
|
|
73
|
+
"oneLakeTablesPath": "https://onelake.dfs.fabric.microsoft.com/{workspaceId}/{itemId}/Tables",
|
|
74
|
+
"oneLakeFilesPath": "https://onelake.dfs.fabric.microsoft.com/{workspaceId}/{itemId}/Files",
|
|
75
|
+
"sqlEndpointProperties": {
|
|
76
|
+
"connectionString": "xxxxx.datawarehouse.fabric.microsoft.com",
|
|
77
|
+
"id": "37dc8a41-dea9-465d-b528-3e95043b2356",
|
|
78
|
+
"provisioningStatus": "Success"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- **SQL analytics endpoint** → `properties.sqlEndpointProperties.connectionString` (the server for [SQL databases](./add-fabric-resource.md#sql-databases); use the lakehouse item GUID as `database`).
|
|
85
|
+
- **OneLake Files / Tables** → `properties.oneLakeFilesPath` / `oneLakeTablesPath` (the DFS URLs for [OneLake files](./add-fabric-resource.md#onelake-files)).
|
|
86
|
+
|
|
87
|
+
### Warehouse
|
|
88
|
+
|
|
89
|
+
```http
|
|
90
|
+
GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/warehouses/{warehouseId}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"type": "Warehouse",
|
|
96
|
+
"properties": {
|
|
97
|
+
"connectionString": "xxxxx.datawarehouse.fabric.microsoft.com"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- **SQL server** → `properties.connectionString`. Use with [SQL databases](./add-fabric-resource.md#sql-databases); the warehouse item GUID is the `database`.
|
|
103
|
+
|
|
104
|
+
### SQL Database
|
|
105
|
+
|
|
106
|
+
```http
|
|
107
|
+
GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/sqlDatabases/{sqlDatabaseId}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"type": "SQLDatabase",
|
|
113
|
+
"properties": {
|
|
114
|
+
"connectionString": "Data Source=xxxxx.database.fabric.microsoft.com,1433;Initial Catalog=SQLDatabase1-<guid>;Encrypt=True;TrustServerCertificate=False",
|
|
115
|
+
"databaseName": "SQLDatabase1-<guid>",
|
|
116
|
+
"serverFqdn": "xxxxx.database.fabric.microsoft.com,1433"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- **Server** → `properties.serverFqdn`, **database** → `properties.databaseName`. Both are also embedded in `properties.connectionString`.
|
|
122
|
+
|
|
123
|
+
### Eventhouse
|
|
124
|
+
|
|
125
|
+
```http
|
|
126
|
+
GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/eventhouses/{eventhouseId}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"type": "Eventhouse",
|
|
132
|
+
"properties": {
|
|
133
|
+
"queryServiceUri": "https://xxxxx.z5.kusto.fabric.microsoft.com",
|
|
134
|
+
"ingestionServiceUri": "https://ingest-xxxxx.z5.kusto.fabric.microsoft.com",
|
|
135
|
+
"databasesItemIds": ["<kql-database-item-id>"]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **Cluster / query URI** → `properties.queryServiceUri`. Use with [Eventhouse and KQL](./add-fabric-resource.md#eventhouse-and-kql). Each KQL database inside the eventhouse is listed in `databasesItemIds`.
|
|
141
|
+
|
|
142
|
+
## Coordinate lookup table
|
|
143
|
+
|
|
144
|
+
| You need | Item type | Endpoint | Field |
|
|
145
|
+
| ------------------------------ | ------------ | ----------------------- | --------------------------------------------------- |
|
|
146
|
+
| SQL server (Lakehouse) | Lakehouse | `.../lakehouses/{id}` | `properties.sqlEndpointProperties.connectionString` |
|
|
147
|
+
| SQL server (Warehouse) | Warehouse | `.../warehouses/{id}` | `properties.connectionString` |
|
|
148
|
+
| SQL server + database (SQL DB) | SQL Database | `.../sqlDatabases/{id}` | `properties.serverFqdn` / `properties.databaseName` |
|
|
149
|
+
| OneLake Files / Tables URL | Lakehouse | `.../lakehouses/{id}` | `properties.oneLakeFilesPath` / `oneLakeTablesPath` |
|
|
150
|
+
| Kusto query URI | Eventhouse | `.../eventhouses/{id}` | `properties.queryServiceUri` |
|
|
151
|
+
| Item GUID (any item) | any | `.../items?type={Type}` | `id` |
|
|
152
|
+
|
|
153
|
+
For item types not listed here, browse the [Fabric REST API item reference](https://learn.microsoft.com/en-us/rest/api/fabric/) — each item's **Get** operation returns its coordinates under `properties`.
|
|
154
|
+
|
|
155
|
+
## Notes
|
|
156
|
+
|
|
157
|
+
- **OneLake paths are constructable.** Every OneLake path follows `https://onelake.dfs.fabric.microsoft.com/{workspaceId}/{itemId}/Files/...` — if you already have the workspace and item GUIDs you can build the URL without a lookup.
|
|
158
|
+
- **The item GUID is the `database` for SQL.** Fabric Lakehouse/Warehouse queries route by item GUID, not display name — see [SQL databases](./add-fabric-resource.md#sql-databases).
|
|
159
|
+
- **Read permission required.** The `Get` endpoints need `Item.Read.All` (or the item-specific read scope) on the delegated token. If a lookup 403s, the signed-in user lacks read access to that item.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 5
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Connecting to external resources
|
|
6
|
+
|
|
7
|
+
Functions can call external Azure and Fabric resources **as the calling user** using delegated authentication.
|
|
8
|
+
You declare a connection on the function, and at invocation time the runtime exchanges the user's identity for a resource-scoped on-behalf-of (OBO) token.
|
|
9
|
+
|
|
10
|
+
## The pattern
|
|
11
|
+
|
|
12
|
+
Declare an audience-scoped connection in the third argument of `udf.func()`, then read its token with `ctx.getToken()`:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import {
|
|
16
|
+
UserDataFunctions,
|
|
17
|
+
AudienceType,
|
|
18
|
+
type RayfinContext,
|
|
19
|
+
} from "@microsoft/fabric-user-data-functions";
|
|
20
|
+
|
|
21
|
+
const udf = new UserDataFunctions();
|
|
22
|
+
|
|
23
|
+
udf.func(
|
|
24
|
+
"myFunction",
|
|
25
|
+
async (ctx: RayfinContext): Promise<string> => {
|
|
26
|
+
const token = ctx.getToken(AudienceType.KeyVault);
|
|
27
|
+
// Use `token` with the resource's SDK or REST API.
|
|
28
|
+
return "ok";
|
|
29
|
+
},
|
|
30
|
+
[udf.connection({ audienceType: AudienceType.KeyVault })],
|
|
31
|
+
);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- `udf.connection({ audienceType })` declares the delegated connection.
|
|
35
|
+
- `ctx.getToken(audienceType)` returns the OBO access token as a `string`. It throws if no connection was declared for that audience.
|
|
36
|
+
- The connection declaration is what makes the token available — declaring the audience and calling `getToken` with the same audience always go together.
|
|
37
|
+
|
|
38
|
+
## Wrapping the token for Azure SDK clients
|
|
39
|
+
|
|
40
|
+
Many Azure SDK clients expect a `TokenCredential` rather than a raw token string.
|
|
41
|
+
Define a small adapter that returns the token from the context:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import type { TokenCredential, AccessToken } from "@azure/identity";
|
|
45
|
+
|
|
46
|
+
class ContextTokenCredential implements TokenCredential {
|
|
47
|
+
constructor(private readonly token: string) {}
|
|
48
|
+
async getToken(): Promise<AccessToken> {
|
|
49
|
+
return { token: this.token, expiresOnTimestamp: Date.now() + 3600_000 };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Pass `new ContextTokenCredential(ctx.getToken(AudienceType.X))` wherever an Azure SDK client asks for a credential.
|
|
55
|
+
The per-resource guides below use this helper.
|
|
56
|
+
|
|
57
|
+
## Choose a recipe
|
|
58
|
+
|
|
59
|
+
Find what you want to connect to. Each row links to a task-oriented walkthrough; the `AudienceType` is the value you pass to `udf.connection()` and `ctx.getToken()`. A single audience can back more than one use case (for example `Storage` covers both Fabric OneLake and Azure Blob).
|
|
60
|
+
|
|
61
|
+
| I want to connect to… | `AudienceType` | Recipe |
|
|
62
|
+
| ------------------------------------------------ | -------------- | -------------------------------------------------------------------- |
|
|
63
|
+
| Fabric Lakehouse / Warehouse / SQL DB / Mirrored | `Sql` | [Add a Fabric resource](./add-fabric-resource.md#sql-databases) |
|
|
64
|
+
| Azure SQL Database | `Sql` | [Add a Fabric resource](./add-fabric-resource.md#sql-databases) |
|
|
65
|
+
| Fabric OneLake files | `Storage` | [Add a Fabric resource](./add-fabric-resource.md#onelake-files) |
|
|
66
|
+
| Azure Blob / Table / Queue | `Storage` | [Add an Azure resource](./add-azure-resource.md#blob-storage) |
|
|
67
|
+
| Fabric Eventhouse (KQL) | `Kusto` | [Add a Fabric resource](./add-fabric-resource.md#eventhouse-and-kql) |
|
|
68
|
+
| Azure Data Explorer | `Kusto` | [Add a Fabric resource](./add-fabric-resource.md#eventhouse-and-kql) |
|
|
69
|
+
| Microsoft Fabric REST API | `Fabric` | [Add a Fabric resource](./add-fabric-resource.md#fabric-rest-api) |
|
|
70
|
+
| Azure Key Vault | `KeyVault` | [Add an Azure resource](./add-azure-resource.md#key-vault) |
|
|
71
|
+
| Azure Cosmos DB | `CosmosDB` | [Add an Azure resource](./add-azure-resource.md#cosmos-db) |
|
|
72
|
+
| Azure Event Grid | `EventGrid` | [Add an Azure resource](./add-azure-resource.md#event-grid) |
|
|
73
|
+
| Azure AI Foundry | `AzureAI` | [Add Azure AI Foundry](./add-foundry.md) |
|
|
74
|
+
| Azure DevOps | `ADO` | [Add Azure DevOps](./add-ado.md) |
|
|
75
|
+
| WorkIQ | `WorkIQ` | [Add WorkIQ](./add-work-iq.md) |
|
|
76
|
+
|
|
77
|
+
To look up a Fabric item's connection coordinates (SQL endpoint, OneLake path, Kusto query URI), see [Get Fabric info](./get-fabric-info.md).
|
|
78
|
+
|
|
79
|
+
## Rules
|
|
80
|
+
|
|
81
|
+
- **Use real endpoint URLs** — don't hardcode a guess or read them from `process.env`. For Fabric items, [Get Fabric info](./get-fabric-info.md) shows how to look them up.
|
|
82
|
+
- Declare every connection in the third argument to `udf.func()`.
|
|
83
|
+
- Use `ctx.getToken(AudienceType.X)` — never acquire tokens manually.
|
|
84
|
+
- Install resource SDK packages in `rayfin/functions/package.json`, not the project root.
|
|
85
|
+
|
|
86
|
+
## Local development
|
|
87
|
+
|
|
88
|
+
When you run `npx rayfin dev functions apply`, the local host acquires delegated tokens interactively for debugging, so `ctx.getToken()` works against your declared audiences without a deployment.
|
|
89
|
+
See [`npx rayfin dev functions apply`](../../cli/functions/dev-apply.md).
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 35
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Functions
|
|
6
|
+
|
|
7
|
+
Rayfin functions are server-side user-defined functions (UDFs) that run in the Fabric runtime and are invocable from your frontend through `RayfinClient`.
|
|
8
|
+
Write trusted backend logic once, get a type-safe client call on the frontend.
|
|
9
|
+
|
|
10
|
+
## When to use functions
|
|
11
|
+
|
|
12
|
+
Reach for a function whenever logic should run on the backend rather than in the browser:
|
|
13
|
+
|
|
14
|
+
- **Sensitive operations** — code that touches secrets, API keys, or privileged data access.
|
|
15
|
+
- **Business logic that must not be tampered with** — anything you would not want a user to inspect or modify in client code.
|
|
16
|
+
- **Server-side validation** — enforce rules that a malicious client could otherwise bypass.
|
|
17
|
+
- **Aggregation and transformation** — shape or combine data before returning it to the client.
|
|
18
|
+
|
|
19
|
+
If a frontend feature needs trusted server-side behavior, implement it as a function.
|
|
20
|
+
|
|
21
|
+
## Getting started
|
|
22
|
+
|
|
23
|
+
Scaffold the functions project with the CLI:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx rayfin functions init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This creates `rayfin/functions/`, installs dependencies, and generates the initial `types.ts`.
|
|
30
|
+
See [`npx rayfin functions init`](../cli/functions/init.md) for the full command reference.
|
|
31
|
+
|
|
32
|
+
## Project structure
|
|
33
|
+
|
|
34
|
+
After `npx rayfin functions init`, the functions project lives at `rayfin/functions/`:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
rayfin/
|
|
38
|
+
├── data/ ← entity classes (shared via TS project references)
|
|
39
|
+
└── functions/
|
|
40
|
+
├── src/
|
|
41
|
+
│ ├── function_app.ts ← register your functions here
|
|
42
|
+
│ └── types.ts ← auto-generated schema (do not edit)
|
|
43
|
+
├── package.json
|
|
44
|
+
├── tsconfig.json ← references: [{ "path": ".." }]
|
|
45
|
+
├── host.json
|
|
46
|
+
└── local.settings.json ← local-only settings (git-ignored)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`tsconfig.json` uses `composite: true` with a project reference to `rayfin/`, so functions can `import type` from your data entities without duplicating definitions.
|
|
50
|
+
|
|
51
|
+
## Your first function
|
|
52
|
+
|
|
53
|
+
The scaffold seeds `src/function_app.ts` with a simple example:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { UserDataFunctions } from "@microsoft/fabric-user-data-functions";
|
|
57
|
+
|
|
58
|
+
const udf = new UserDataFunctions();
|
|
59
|
+
|
|
60
|
+
udf.func(
|
|
61
|
+
"helloWorld",
|
|
62
|
+
(firstName: string, lastName: string): string => {
|
|
63
|
+
console.log(`helloWorld invoked for ${firstName} ${lastName}`);
|
|
64
|
+
return `Hello ${firstName} ${lastName}!`;
|
|
65
|
+
},
|
|
66
|
+
[],
|
|
67
|
+
);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The handler's parameter and return types are read by typegen and written into `types.ts` so the frontend can call `client.functions.helloWorld.invoke({ firstName, lastName })` with full type safety.
|
|
71
|
+
|
|
72
|
+
## The development loop
|
|
73
|
+
|
|
74
|
+
For local development, prefer `npx rayfin dev`; it starts the frontend and functions together automatically.
|
|
75
|
+
To iterate on functions **without** starting the frontend static app, run only the function host:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx rayfin dev functions apply
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This starts a local function host, keeps a typegen watcher running, and publishes its URL for local frontend routing.
|
|
82
|
+
Bundled Vite apps use the same-origin `/.rayfin/api/<name>` route when you run the frontend separately.
|
|
83
|
+
See [`npx rayfin dev functions apply`](../cli/functions/dev-apply.md) for details.
|
|
84
|
+
|
|
85
|
+
## Next steps
|
|
86
|
+
|
|
87
|
+
- [Writing functions](./writing-functions.md) — the `udf.func()` API, `RayfinContext`, and data access.
|
|
88
|
+
- [Type generation](./typegen.md) — how `types.ts` is generated and kept in sync.
|
|
89
|
+
- [Connecting to external resources](./connections/index.md) — delegated access to SQL, Storage, Key Vault, and more.
|
|
90
|
+
- [Secrets](./secrets.md) — reading secrets from inside a function.
|
|
91
|
+
- [Invoking functions from the frontend](./invoking-from-frontend.md) — calling functions with `RayfinClient`.
|