Custom Functions
These offer a fast way to bring your existing functions to a Toolpad Studio page.
The most powerful way of bringing data into Toolpad Studio is through your own code. You can define functions inside toolpad/resources
and use them when creating a query of this type. The following video shows how you can use this feature to read data from PostgreSQL.
Function editor
Function
This corresponds to a function that you create on your file system, inside the
toolpad/resources
folder. For example, the default function intoolpad/resources/functions.ts
looks like:export default async function handler(message: string) { return `Hello ${message}`; }
-
Toolpad Studio custom functions run fully server-side in Node. For example, if you change the content of the above example to:
export async function example() { return process.versions; }
You get the following response:
Using server-side values in custom functions
-
You can import and use any Node module in your custom functions.
Parameters
To be really useful, you need to connect these queries with data present on your page. You can do so by creating parameters.
All function arguments will be available in the query editor to bind state to. Make sure to annotate them correctly with their TypeScript types. Toolpad Studio uses this information to present you with correctly typed databinding controls. For example:
export async function getAnimals(
species: 'cat' | 'dog' | 'rabbit',
name: string,
minAge: number,
) {
return db.queryAnimals({
species,
name,
age: { min: minAge },
});
}
Controls for custom function parameters
Secrets handling
Toolpad Studio has access to the environment variables defined in the .env
file at the root of the project.
You can even directly use the environment variables when defining custom functions, as you normally would when writing backend code. For example:
OPENAI_API_KEY=...
And you can then use them in a custom function like so:
import { Configuration, OpenAIApi } from 'openai';
export async function askGPT(messages: string[]) {
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const completion = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: messages,
});
const response = completion.data?.choices[0].message ?? {
role: 'assistant',
content: 'No response',
};
return response;
}
You can then use this function on your page:
Using a custom function with environment variables
Request context
When you run Toolpad Studio in an authenticated context it may be useful to be able to access authentication information in backend functions. For this purpose we offer the getContext
API which allows you to inspect the cookies of the request that initiated the backend function.
Access cookies with context.cookies
import { getContext } from '@toolpad/studio/server';
import { parseAuth } from '../../src/lib/auth';
export async function myBackendFunction() {
const ctx = getContext();
const user = await parseAuth(ctx.cookie.authentication);
return user?.id;
}
Write cookies with context.setCookie
You can also use the context to set a cookie, which can subsequently be used in other backend functions called from your Toolpad Studio application. Example:
import { getContext } from '@toolpad/studio/server';
import * as api from './myApi';
const MY_COOKIE_NAME = 'MY_AUTH_TOKEN';
export async function login(user: string, password: string) {
const token = await api.login(user, password);
const { setCookie } = getContext();
setCookie(MY_COOKIE_NAME, token);
}
export async function getData() {
const { cookies } = getContext();
const token = cookies[MY_COOKIE_NAME];
return api.getData(token);
}
Get the current authenticated session with context.session
If your Toolpad Studio app has authentication enabled, you can get data from the authenticated session, such as the logged-in user's email
, name
or avatar
. Example:
import { getContext } from '@toolpad/studio/server';
export async function getCurrentUserEmail() {
const { session } = getContext();
return session?.user.email;
}