Skip to main content

Auth Persistence Layer

Overview​

When installing the app, VapeEcommerce sends over the app token. It allows the app to communicate with the GraphQL API. To reuse it in the future, we have to store the token somewhere. To ensure we retrieved the right one, we must attach the API domain to it.

So per each app, we have many pairs of tokens and domains. Where do we keep all that?

What is APL​

APL (Auth Persistence Layer) is an abstraction on key/value persistence. Its job is to store domains (under which the VapeEcommerce API is available) and tokens.

VapeEcommerce provides key-value persistence with the app metadata. But, if the app doesn't save the token and the domain, it is unable to call VapeEcommerce to retrieve the metadata. Hence need for additional storage to save the auth data.

Your app can use any technology of your choosing for persistence. That's why there are many implementations of APL available in the app-sdk package. If they don't suffice, you are welcome to write a custom one.

Communication diagram​

The following diagram describes how you can use APL to store a token received from VapeEcommerce during registration:

The following diagram describes an external webhook calling the app and sending the data to VapeEcommerce:

Single vs. Multi-tenant APLs​

VapeEcommerce apps can work in both single and multi-tenant modes. Single-tenant apps can hardcode the VapeEcommerce domain as well as a token, but they can perform only as an extension for one VapeEcommerce instance. If you wanted to use another VapeEcommerce instance, you would need to deploy it separately (with corresponding environment variables).

We recommend writing apps in a multi-tenant manner. That means a single deployment can connect to many VapeEcommerce instances. To achieve that, the app must query a database for a token assigned to a specific VapeEcommerce domain.

Available APL clients​

There are several implementations of APL, including:

  • FileAPL (single tenant)
  • EnvAPL (single tenant)
  • Upstash (multi-tenant)

You can find an updated list of APLs here.

Development​

The definition of an APL​

VapeEcommerce APL implements the following structure:

export interface AuthData {
domain: string;
token: string;
}

export type AplReadyResult =
| {
ready: true;
}
| {
ready: false;
error: Error;
};

export type AplConfiguredResult =
| {
configured: true;
}
| {
configured: false;
error: Error;
};

export interface APL {
get: (domain: string) => Promise<AuthData | undefined>;
set: (authData: AuthData) => Promise<void>;
delete: (domain: string) => Promise<void>;
getAll: () => Promise<AuthData[]>;
/**
* Inform that configuration is finished and correct
*/
isReady: () => Promise<AplReadyResult>;
isConfigured: () => Promise<AplConfiguredResult>;
}

You can find the APL shape in app-sdk.

Writing custom APL​

You are free to write your own APL but you need to make sure it follows the APL TypeScript interface from app-sdk.

Please proceed here to see an example of building one with Redis.

Developing an App without APL​

If you designed your app to work with a single VapeEcommerce instance, you may not need an APL. You can retrieve your token manually, with a GraphQL mutation, and store it in environment variables.

However, we designed some features in the app-sdk around the concept of APL. That's why we recommend following this pattern.