Connections
Overview
Some third party APIs are exposed as multiple instances or environments. For example, in addition to the regular "production" environment, they may expose a "sandbox" environment. The API contract is exactly the same, and the authorization process is exactly the same, but a part of the request (often, the hostname) is different. It can be useful to allow access to all of the environments (called "Connections" in this documentation) through the same ShipEngine Connect App, since most of the code should be exactly the same.
In order to support multiple environments, your AuthProcess definition must
include a connections section. It requires two attributes: connection_names
and default_connection_name.
This page only describes the OAuth aspects of connection names. If you want the user to be presented with a choice of connections in the UI, you must also declare the possible connection names in the
OrderSources.AccountConnectionsection. See the Metadata Definition documentation.
The default_connection_name must define the connection to use when one is
not specified by the end user. In some situations, the end user will not have
a choice, so the connection they use is driven by the default_connection_name.
The value of connection_names is an object keyed by the names (strings) of
the available connections (ex: "production" and "sandbox"). The value of
each entry is a JSON object containing all of the configuration that needs to
vary by connection. Each configuration object should have the same shape for
each connection, but with different values. For example, if you need to vary
the authorization URL by connection, each connection object might have an
authorization_url entry with a different value. The JSON object can take
any shape and be as deep as you need, as long as you can reference the values
you need to extract using JSONPath.
The data in the connection_names section is available to the AuthProcess
definition via the connection_name: template resolver. It can access individual parts of the configuration object via a JSONPath
query. This allows you to vary the OAuth process based on the environment.
The module itself can also vary its logic based on the connection. For apps
that define connection_names, each incoming request to their functions
will include a request.auth.connection_name property indicating which
environment to use for the given request.
Pro Tip
These AuthProcess definitions cannot access other environment variables as defined in the Manage Configuration documentation. For example, if you set the following in a constants.ts file:
export const API_URL = process.env.API_URL ?? 'https://www.sandbox.example.com/api';API_URL will not have access to check the process.env if you try to use API_URL in your AuthProcess definitions which typically results in unexpected values running in a production environment.
Example
Consider this example (partial) AuthProcess definition:
authorization: {
url_template: '{connection_name:$.url}/oauth2/auth',
},
// ... elided irrelevant sections
connections: {
default_connection_name: 'production',
connection_names: {
sandbox: {
url: https://api-sandbox.example.com
},
production: {
url: https://api.example.com
},
}
}For this 3rd party, the URL that will be used during the authorization phase
needs to be different, depending on if you are accessing their production
environment, or their sandbox environment. Therefore, the url_template
makes use of the connection_name resolver to substitute in a value from
the connections section. The connection_name resolver will automatically
scope to the connection_names section based on the connection chosen for
the current process. It will then apply the $.url JSONPath to pull out the
value it needs. So if a user starts the OAuth flow and indicates they want
the sandbox environment, the {connection_name:$.url} template value will
resolve to https://api-sandbox.example.com.
After the connection is established and a request is made to the app's functions, the app can vary its logic based on the connection:
const baseUrl = (request.auth.connection_name==='sandbox') ?
"https://api-sandbox.example.com" :
"https://sandbox.example.com";