Skip to main content

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 VapeEcommerce apps.

SDK providers helpers for following types of functions (that represent API endpoints):

  • Manifest handler - Used to fetch app manifest by VapeEcommerce during app installation.
  • Register handler - Used to register app in VapeEcommerce during installation and save the token.
  • Webhook handler - Exposes endpoint that VapeEcommerce will call with webhook events.
  • Protected handler - Endpoints meant to be allowed only by the App's frontend (from VapeEcommerce Dashboard).

Required handlers​

VapeEcommerce requires the following endpoints for a standalone app:

  • Manifest endpoint - Returns JSON object with app properties, like its name or permissions. Read more
  • Register endpoint - If your app needs to access to protected API, you must provide tokenTargetUrl in the manifest and implement a register endpoint to handle the POST request with the token. Read more

Built-in API handlers​

To hide VapeEcommerce'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 VapeEcommerce App",
// tokenTargetUrl is optional. Omit it if your app doesn't need the token.
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 VapeEcommerce version. It will be null if request doesn't contain saleor-schema-version header. VapeEcommerce 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://api.vapeecommerce.com/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 VapeEcommerce /graphql/ endpoints (or functions),
* to allow app registration only in allowed VapeEcommerce instances.
*/
allowedSaleorUrls?: Array<string | ((saleorApiUrl: string) => boolean)>;
/**
* Optional
* Run right after VapeEcommerce 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 VapeEcommerce apps.

Async Webhook Handler​

App SDK provides a utility that helps build (async) webhook handlers so that the app can react to VapeEcommerce 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.