createClient
createClient creates a client object that matches your server's app object for seamless development.
Type definition
type ClientConfig = {
auth?: string;
requestInit?: RequestInit | (() => RequestInit);
subscribeKey?: string;
};
const createClient = <T extends IntegroApp>(url = '/', config?: ClientConfig) => IntegroClient;Usage
createClient can be called on the client side if you include integro as a client-side dependency.
import { createController } from 'integro/client';
import type { App } from '@/api/app';
export apiClient = createClient<App>('https://example.com');export const app = {
version: () => '1.0.0',
greetings: {
sayHello: (name: string) => `Hello, ${name}!`,
sayGoodbye: (name: string) => `Goodbye, ${name}!`,
},
};
export type App = typeof app;For easier dependency management and simpler typing, we recommend having your server app publish its own strongly-typed version of createClient:
import { createApiClient } from '@/api/createApiClient';
export apiClient = createApiClient<App>('https://example.com');import { createController } from 'integro/client';
import type { app } from './api';
export createApiClient = createClient<typeof app>;export const app = {
version: () => '1.0.0',
greetings: {
sayHello: (name: string) => `Hello, ${name}!`,
sayGoodbye: (name: string) => `Goodbye, ${name}!`,
},
};Parameters
createClient has 2 optional parameters:
url
Type: string
Default: "/"
The first parameter to createClient is an optional string representing the path your server is running on.
config
Type: ClientConfig
Default: {}
The second parameter to createClient is a configuration object which allows you to manipulate the Request before sending it to the server.
config.auth
Type: string | (() => string | undefined)
Default: undefined
Auth token sent in request's "Authorization" header and websocket message body. If supplied, requestInit.header.Authorization overrides auth during fetches. auth will be used by websockets regardless.
import { createApiClient } from '@/api';
import { getCurrentAuthToken } from './authService';
export const api = createClient<App>('https://example.com', {
auth: () => {
const currentAuthToken = getCurrentAuthToken();
return currentAuthToken && `bearer ${currentAuthToken}`;
}),
});config.requestInit
Type: RequestInit | (() => RequestInit)
Default: undefined
requestInit is a standard RequestInit object or a function returning one. It may be used for supporting CORS, cross-site cookies, authentication, and other business requirements.
import { createApiClient } from '@/api';
export const api = createApiClient("https://example.com", {
requestInit: {
headers: {
credentials: 'include',
},
},
});import { createApiClient } from '@/api';
import { getCurrentAuthToken } from './authService';
export const api = createClient<App>('https://example.com', {
requestInit: () => {
const currentAuthToken = getCurrentAuthToken();
return currentAuthToken ? {
headers: {
'Authorization': `bearer ${currentAuthToken}`,
},
} : {};
}),
});config.subscribeKey
Type: string
Default: "subscribe"
The leaf endpoint which will trigger a subscription. If creating subscribable endpoints using createSubject, then the default "subscribe" should be used.
IntegroPromise behavior
All client methods return instances of IntegroPromise. These are "lazy" promises, which means they only execute when you call await, .then(), .catch() or .finally(). This makes it possible to batch API calls.
const promise = api.artists.findById(validId); // not executed yet
await promise; // executed hereMost of the time, you'll await a method immediately. But in cases where you need to begin execution immediately without waiting for the results, you can trigger the execution with .then() without passing it a callback.
test('it fetches an artist from the API', () => {
const promise = api.artists.findById(validId).then();
expect(promise).resolves.toEqual({ /* ... */ });
});