Skip to main content

Using multiple providers

Consuming a single use case from multiple providers is at heart of Superface. You can add as many providers as you need for every profile.

This guide will walk you through the process of configuring these providers the way you need them to work. You'll need a Node.js app with OneSDK and a use case set up. We recommend you to read through the Getting started first if you haven’t done so.

There are currently 2 different ways you might want to switch between the providers:

Manual provider selection

In integration scenarios where you need to fulfill the use case by the specific provider (e.g. because the user content is saved on their servers), you can manually choose which provider you want to use.

The provider choice is bound to a single perform. This means you can choose different providers for different perform calls.

It works by passing the chosen provider configuration to perform method on the use case. You can fetch the provider configuration in runtime using getProvider method exposed from OneSDK.

Example

Let's say your app lists user repositories and you want to support multiple version control systems. You'd use vcs/user-repos and will configure all supported VCS providers.

cd your-app/
npx @superfaceai/cli@3 configure github --profile=vcs/user-repos
npx @superfaceai/cli@3 configure gitlab --profile=vcs/user-repos
npx @superfaceai/cli@3 configure bitbucket --profile=vcs/user-repos

Then, switching between the 3 configured providers would look like this:

app.js
const { SuperfaceClient } = require('@superfaceai/one-sdk');

const sdk = new SuperfaceClient();

async function run() {
const profile = await sdk.getProfile('vcs/user-repos');

// Load the specific provider for this perform
const provider = await sdk.getProvider('github');

const result = await profile
.getUseCase('UserRepos')
.perform({ user: 'superfaceai' }, { provider });

return result.unwrap();
}

run();
note

If there's only one provider configured for the profile, that provider is automatically used and you don't have to explicitly choose the provider in the code.

Automatic failover

When using provider failover, OneSDK will automatically switch to another provider in the case of failure.

This will give you a maximum out-of-the-box resiliency useful for integration scenarios where you don't care so much about which provider fulfills the use case but you need it to happen reliably (e.g. in commodity use cases like sending emails, SMS, etc).

Enabling failover

The failover has to be configured for each use case separately by enabling providerFailover option in the use case defaults.

For example, if you want to send SMS messages reliably, you'll use the SendMessage use case from communication/send-sms and have two or three providers configured.

Then, the configuration of the failover for SendMessage use case would look like this:

superface/super.json
{
"profiles": {
"communication/send-sms": {
"version": "1.0.1",
"defaults": {
"SendMessage": {
"providerFailover": true
}
},
"priority": [
// ...
],
"providers": {
// ...
}
}
},
"providers": {
// ...
}
}

For more information about the use case defaults, please see super.json reference.

Specifying failover order

By default, OneSDK uses the first provider that was added to the application as primary, with failover to other providers in order they were added to the app. You can specify your preferred order in which OneSDK should use and fail over between the providers.

For example, you're using communication/send-sms to send SMS reliably and have 3 providers configured (e.g. tyntec, plivo and twilio).

You want to primarily use twilio. If that fails, you prefer plivo and if the secondary fails as well, you want to switch to tyntec. The configuration of the provider priority for this case would look like this:

superface/super.json
{
"profiles": {
"communication/send-sms": {
"version": "1.0.1",
"defaults": {
"SendMessage": {
"providerFailover": true
}
},
"priority": ["twilio", "plivo", "tyntec"],
"providers": {
// ...
}
}
},
"providers": {
// ...
}
}

Retry on failure

By default, OneSDK attempts to perform the use case with each provider exactly once.

OneSDK also ships with a configurable circuit breaker retry policy. The retry policy has to be configured for each provider by setting retryPolicy option in the use case defaults for provider.

For example, enabling the circuit breaker retry policy for twilio when performing SendMessage use case (from communication/send-sms) would look like the snippet below.

The default circuit breaker policy makes 5 retries using an exponential backoff and times out after 30 seconds. For full retry configuration, please see super.json reference.

superface/super.json
{
"profiles": {
"communication/send-sms": {
"version": "1.0.1",
"defaults": {
// ...
},
"priority": [
// ...
],
"providers": {
"twilio": {
"defaults": {
"SendMessage": {
"retryPolicy": "circuit-breaker"
// ...
}
}
}
}
}
},
"providers": {
// ...
}
}

Failover in code

When using automatic failover, your code doesn't need to specify anything about the providers. The priority of providers, their behavior and failover is configured solely in your local super.json file.

For example, using communication/send-sms to send SMS reliably with multiple providers configured using automatic failover, your application code for performing SendMessage would look like this (note that there's no provider-specific information included):

app.js
const { SuperfaceClient } = require('@superfaceai/one-sdk');

const sdk = new SuperfaceClient();

async function run() {
// Load the installed profile
const profile = await sdk.getProfile('communication/send-sms');

// Use the profile
const result = await profile.getUseCase('SendMessage').perform({
to: '+123456789',
from: '+987654321',
text: 'Really important message!',
});

return result.unwrap();
}

run();
caution

Automatic failover cannot be combined with manual provider selection.