API Handlers
App SDK mainly targets serverless environments, like Vercel functions or AWS Lambda. It provides a set of handlers that can be used to build Saleor apps.
SDK providers helpers for following types of functions (that represent API endpoints):
- Manifest handler - Used to fetch app manifest by Saleor during app installation.
- Register handler - Used to register app in Saleor during installation and save the token.
- Webhook handler - Exposes endpoint that Saleor will call with webhook events.
- Protected handler - Endpoints meant to be allowed only by the App's frontend (from Saleor Dashboard).
Required handlers​
Saleor requires two endpoints to be available for a standalone app:
- Manifest endpoint - Returns JSON object with app properties, like its name or permissions. Read more
- Register endpoint - During installation, Saleor sends a
POST
request with auth token to this endpoint. Read more
Built-in API handlers​
To hide Saleor's internal logic, app-sdk provides handlers factories. They should work with minimal configuration, leaving App creators space for domain logic.
Manifest handler factory​
Here is an example usage of a manifest handler in Next.js:
// pages/api/manifest.ts
// Change "next" to other platforms if needed
import { createManifestHandler } from "@saleor/app-sdk/handlers/next";
export default createManifestHandler({
manifestFactory({ request, appBaseUrl, schemaVersion }) {
return {
name: "My Saleor App",
tokenTargetUrl: `${appBaseUrl}/api/register`,
appUrl: appBaseUrl,
permissions: ["MANAGE_USERS"],
id: "my-saleor-app",
version: "1",
};
},
});
<PLATFORM>
is one of the supported platforms, like NextJS or Lambda
Options provided to handler factory:
type CreateManifestHandlerOptions = {
manifestFactory(context: {
appBaseUrl: string;
request: Request; // Depends on the platform, e.g. Request, NextApiRequest, NextRequest
schemaVersion: [major: number, minor: number] | null;
}): AppManifest; // Ensures response type is valid
};
You can use request
to read additional parameters from the request.
Field schemaVersion
can be used to enable some feature based on the Saleor version. It will be null
if request doesn't contain saleor-schema-version
header.
Saleor will automatically attach this header, but the GET request executed e.g. from the browser will not contain this field.
Hint: @saleor/app-sdk
contains documented types attached to the npm package.
App register handler factory​
Following example shows how to use a register handler in Next.js:
// pages/api/register.ts - next.js route
import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
import { UpstashAPL } from "@saleor/app-sdk/APL/upstash"; // See APL section
export default createAppRegisterHandler({
apl: new UpstashAPL({
restURL: "...",
restToken: "...",
}),
allowedSaleorUrls: ["https://your-saleor.saleor.cloud/graphql/"], // optional, see options below
async onRequestVerified(req, { authData, respondWithError }) {
await doSomethingAndBlockInstallation(authData.token).catch((err) => {
// Return this method to break installation flow and show error in the Dashboard
return respondWithError({ message: "Error, installation will fail" });
});
},
});
Options provided to handler factory
export type CreateAppRegisterHandlerOptions = {
apl: APL;
/**
* Provide your Saleor /graphql/ endpoints (or functions),
* to allow app registration only in allowed Saleor instances.
*/
allowedSaleorUrls?: Array<string | ((saleorApiUrl: string) => boolean)>;
/**
* Optional
* Run right after Saleor calls this endpoint
*/
onRequestStart?(
request: Request, // Can be different depending on the platform
context: {
authToken?: string;
saleorDomain?: string;
saleorApiUrl?: string;
respondWithError: ({ status, message }) => never; // will throw
}
): Promise<void>;
/**
* Optional
* Run after all security checks
*/
onRequestVerified?(
request: Request,
context: {
authData: AuthData;
respondWithError: ({ status, message }) => never; // will throw
}
): Promise<void>;
/**
* Optional
* Run after APL successfully AuthData, assuming that APL.set will reject a Promise in case of error
*/
onAuthAplSaved?(
request: Request,
context: {
authData: AuthData;
respondWithError: ({ status, message }) => never; // will throw
}
): Promise<void>;
/**
* Optional
* Run after APL fails to set AuthData
*/
onAplSetFailed?(
request: Request,
context: {
authData: AuthData;
error: unknown;
respondWithError: ({ status, message }) => never; // will throw
}
): Promise<void>;
};
See APL for details on what is Auth Persistence Layer in Saleor apps.
Async Webhook Handler​
App SDK provides a utility that helps build (async) webhook handlers so that the app can react to Saleor events.
Read about it here.
Protected handler​
To protect endpoint from the outside world and accept only requests from the app's frontend, use the createProtectedHandler
function.
See more details here.