2022-09-21 09:25:01 +00:00
# Api Handlers
Saleor Apps are meant to work in serverless environment, where Cloud Functions are the foundations of server-side code.
Currently, Saleor heavily relies on Next.js, but in the future, other platforms will be supported.
## Required handlers
Saleor requires 2 endpoints to be available for a standalone app:
- Manifest endpoint - Returns JSON object with app properties, like its name or permissions. [Read more ](https://docs.saleor.io/docs/3.x/developer/extending/apps/manifest )
- Register endpoint - During the installation process, Saleor sends `POST` request with auth token to this endpoint. [Read more ](https://docs.saleor.io/docs/3.x/developer/extending/apps/installing-apps#installation-using-graphql-api )
## Api handlers built-in SDK
To hide Saleor internal logic, app-sdk provides handlers factories. They should work with minimal configuration, leaving
App creators space for domain logic.
### Manifest handler factory
Example usage of manifest handler in Next.js
```typescript
// pages/api/manifest.ts
2022-10-05 13:41:27 +00:00
import { createManifestHandler } from "@saleor/app-sdk/handlers/next";
2022-09-21 09:25:01 +00:00
export default createManifestHandler({
2023-06-22 09:32:11 +00:00
manifestFactory({ request, appBaseUrl }) {
2022-09-21 09:25:01 +00:00
return {
name: "My Saleor App",
2023-06-22 09:32:11 +00:00
tokenTargetUrl: `${appBaseUrl}/api/register` ,
appUrl: appBaseUrl,
2022-09-21 09:25:01 +00:00
permissions: [],
id: "my-saleor-app",
version: "1",
};
},
});
```
Options provided to handler factory
```typescript
type CreateManifestHandlerOptions = {
2023-06-22 09:32:11 +00:00
manifestFactory(context: { appBaseUrl: string; request: NextApiRequest }): AppManifest;
2022-09-21 09:25:01 +00:00
};
```
2023-06-22 09:32:11 +00:00
You can use NextApiRequest to read additional params from request. For example read Saleor version to enable or disabled some features, depending on their support.
2022-09-21 09:25:01 +00:00
See [source ](./src/handlers/next/create-manifest-handler.ts ) for more details. See [manifest ](../src/types.ts ) too.
### App register handler factory
Example usage of app register handler in Next.js
```typescript
// pages/api/register.ts
2022-10-05 13:41:27 +00:00
import { createAppRegisterHandler } from "@saleor/app-sdk/handlers/next";
2023-02-26 17:35:04 +00:00
import { UpstashAPL } from "@saleor/app-sdk/APL";
2022-09-21 09:25:01 +00:00
export default createAppRegisterHandler({
2023-02-26 17:35:04 +00:00
apl: new UpstashAPL({
restURL: "...",
restToken: "...",
}),
2023-01-19 13:17:36 +00:00
allowedSaleorUrls: ["https://your-saleor.saleor.cloud/graphql/"], // optional, see options below
2023-02-27 13:36:22 +00:00
async onRequestVerified(req, { authData, respondWithError }) {
await doSomethingAndBlockInstallation(authData.token).catch((err) => {
2023-02-28 12:54:58 +00:00
// Return this method to break installation flow and show error in the Dashboard
return respondWithError({ message: "Error, installation will fail" });
2023-02-27 13:36:22 +00:00
});
},
2022-09-21 09:25:01 +00:00
});
```
Options provided to handler factory
```typescript
export type CreateAppRegisterHandlerOptions = {
apl: APL;
2023-01-19 13:17:36 +00:00
/**
* Provide your Saleor /graphql/ endpoints (or functions),
* to allow app registration only in allowed Saleor instances.
*/
allowedSaleorUrls?: Array< string | ( ( saleorApiUrl: string ) = > boolean)>;
2023-02-27 13:36:22 +00:00
/**
* Optional
* Run right after Saleor calls this endpoint
*/
onRequestStart?(
request: Request,
context: {
authToken?: string;
saleorDomain?: string;
saleorApiUrl?: string;
2023-02-28 12:54:58 +00:00
respondWithError: ({ status, message }) => never; // will throw
2023-02-27 13:36:22 +00:00
}
): Promise< void > ;
/**
* Optional
* Run after all security checks
*/
onRequestVerified?(
request: Request,
context: {
authData: AuthData;
2023-02-28 12:54:58 +00:00
respondWithError: ({ status, message }) => never; // will throw
2023-02-27 13:36:22 +00:00
}
): 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;
2023-02-28 12:54:58 +00:00
respondWithError: ({ status, message }) => never; // will throw
2023-02-27 13:36:22 +00:00
}
): Promise< void > ;
/**
* Optional
* Run after APL fails to set AuthData
*/
onAplSetFailed?(
request: Request,
context: {
authData: AuthData;
error: unknown;
2023-02-28 12:54:58 +00:00
respondWithError: ({ status, message }) => never; // will throw
2023-02-27 13:36:22 +00:00
}
): Promise< void > ;
2022-09-21 09:25:01 +00:00
};
```
See [APL ](./apl.md ) for details what is Auth Persistence Layer in Saleor apps
2022-11-22 10:46:05 +00:00
### Async Webhook Handler
App SDK provides a utility that helps building (async) webhook handlers, so app can react on Saleor events.
2023-01-19 13:17:36 +00:00
Read about it [here ](./saleor-async-webhook.md ).