SDK
The type-safe client for the middleware.
The SDK is how your storefront talks to the middleware. It turns the endpoints interface of an integration into fully typed methods - parameters, return values, and errors all inferred from the middleware's own types.
import { initSDK, buildModule, middlewareModule } from "@alokai/connect/sdk";Build the SDK
middlewareModule generates the client methods from an endpoints interface;
buildModule instantiates it (optionally with an extension); initSDK ties
the modules into the sdk object your app imports.
import { initSDK, buildModule, middlewareModule } from "@alokai/connect/sdk";
import type { SapccEndpoints } from "storefront-middleware/types";
const sdkConfig = {
commerce: buildModule(middlewareModule<SapccEndpoints>, {
apiUrl: "http://localhost:4000/commerce",
}),
};
export const sdk = initSDK<typeof sdkConfig>(sdkConfig);
// fully typed, end to end:
const products = await sdk.commerce.getProducts({ pageSize: 20 });Module options
Everything middlewareModule accepts. Only apiUrl is required - defaults,
custom HTTP clients, error handling, and logging are all opt-in.
Prop
Type
Per-request configuration
Any SDK call accepts a request config alongside its parameters - wrap it in
prepareConfig to distinguish it from method params. Use it to switch the
HTTP method, add headers, or stream the response.
import { prepareConfig } from "@alokai/connect/sdk";
const products = await sdk.commerce.getProducts(
params,
prepareConfig({ method: "GET" }),
);Prop
Type
Error handling
Failed requests throw an SdkHttpError carrying the HTTP status code and
the middleware's error message. Type-safe guards let you branch on the
failure class without inspecting the error shape by hand:
import {
isSdkRequestError,
isSdkServerError,
isSdkUnauthorizedError,
} from "@alokai/connect/sdk";
try {
await sdk.commerce.getProduct({ id });
} catch (error) {
if (isSdkUnauthorizedError(error)) {
// 401/403: redirect to login
} else if (isSdkRequestError(error)) {
// 4xx: invalid input, show a message
} else if (isSdkServerError(error)) {
// 5xx: retry or show a maintenance page
}
throw error;
}For cross-cutting recovery - refreshing tokens, retrying, central reporting -
give the module an errorHandler in its options instead
of wrapping every call site:
const options = {
apiUrl: "https://api.example.com",
errorHandler: async ({ error, methodName, url, params, config, httpClient }) => {
if (error.status === 401 && methodName !== "login") {
await refreshToken();
return httpClient(url, params, config); // retry the request
}
throw error;
},
};