Rayfin

Calling functions from your app

Invoke Rayfin functions from the frontend with a type-safe FunctionClient — client.functions.<name>.invoke() and error handling.

Once a function is registered and its schema is generated (see Writing a function), calling it from the frontend is a single typed call through RayfinClient — no separate HTTP client or manual request shaping.

Warning

Functions are experimental and are not available in every Fabric region or tenant. See Functions before you depend on them.

Give RayfinClient your functions schema

Import the generated AppFunctionsSchema from your functions project and pass it as RayfinClient's second type parameter, alongside your data schema:

src/services/rayfinClient.ts
import { RayfinClient } from '@microsoft/rayfin-client';
import type { AppFunctionsSchema } from '../../rayfin/functions/src/types.js';
import type { AppSchema } from '../../rayfin/data/schema';

const client = new RayfinClient<AppSchema, AppFunctionsSchema>({
  baseUrl: import.meta.env.VITE_RAYFIN_API_URL,
  publishableKey: import.meta.env.VITE_RAYFIN_PUBLISHABLE_KEY,
});

AppFunctionsSchema is a closed object type — only the function names it lists are accepted by client.functions.<name>.invoke(...), and each one's parameter and return types are checked against the schema entry.

Invoking a function

// A function with input:
const greeting = await client.functions.helloWorld.invoke({
  firstName: 'Ada',
  lastName: 'Lovelace',
});
console.log(greeting); // typed as string

// A void-input function (RayfinContext-only handler):
const entries = await client.functions.getEntries.invoke();

invoke() resolves with the function's output directly — Promise<TOutput>, not a wrapper envelope. Pass an options object for extra per-call headers:

await client.functions.helloWorld.invoke(
  { firstName: 'Ada', lastName: 'Lovelace' },
  { headers: { 'x-request-id': crypto.randomUUID() } }
);

Handling errors

invoke() throws rather than returning an error value — by the time it resolves, the result is safe to use without checking for undefined:

import { FunctionsError } from '@microsoft/rayfin-functions';

try {
  const result = await client.functions.helloWorld.invoke({ firstName, lastName });
} catch (error) {
  if (error instanceof FunctionsError) {
    console.error('Function invocation failed:', error.message, error.code);
  } else {
    // NetworkError (transport-level issues) or SdkError (anything else
    // unexpected) from @microsoft/rayfin-lib.
    console.error('Unexpected error calling function:', error);
  }
}
  • A non-empty errors array or a non-success status in the underlying response surfaces as a FunctionsError.
  • Network failures are wrapped in a NetworkError; anything else unexpected is wrapped in a base SdkError.
  • The server-side invocationId is logged via console.debug alongside the function name, so it's available for correlation without being part of the typed return value.

Never call client.functions.<name>.invoke() before functions are deployed — see Deploying functions to enable services.functions and ship your functions project with rayfin up.

PromptCall a Rayfin function from the frontend
In my Rayfin app, wire up calling a function from the frontend: - Update the RayfinClient construction in src/services/rayfinClient.ts to pass AppFunctionsSchema (imported from rayfin/functions/src/types.js) as the second type parameter, alongside my existing data schema. - Call client.functions.<name>.invoke(...) with the right typed parameters, and handle failures by catching FunctionsError from @microsoft/rayfin-functions specifically before falling back to a generic error handler. Show me the updated client setup and the call site.
Something wrong on this page?Report an issueEdit this page

On this page