Proxying Requests

Introduction

Using a proxy server provided by the Managed Runtime’s CDN, you can route requests to APIs hosted on different domains through the same domain as your storefront.
Diagram

Why use the same domain as your storefront? Imagine your storefront is hosted at www.northerntrailoutfitters.com and you want to fetch commerce data by making a request to api.commercecloud.salesforce.com. Making this request without proxying involves extra configuration steps and isn’t as fast and observable as it could be with proxying. Let’s compare the two approaches.

Without ProxyingWith Proxying
You must configure the API server to respond with cross-origin resource sharing (CORS) headers.No extra configuration required for CORS.
API requests require an extra preflight request, slowing performance.No extra network requests made.
If the API server doesn’t cache responses, you lose an opportunity to boost performance significantly.You can instruct the Managed Runtime’s CDN to cache specific requests.
If you don’t have access to the logs for the API server, it’s hard to measure how it affects overall performance.All API requests that are routed through the Managed Runtime’s CDN through proxies are logged.

Now that you understand the value of using proxies, let’s explore the various methods for configuring them.

Configuring the Local Development Environment

For local development, the main way to configure proxies is by editing the mobify.ssrParameters.proxyConfigs array in <PROJECT_DIR>/package.json:

The proxyConfigs array contains objects that define a proxy configuration with the following properties:

  • host: the host that receives your requests, including domain and subdomains.
  • path: the string used in your request paths to trigger proxying.
  • protocol: the network protocol (either http or https). Optional (default value is https).

For PCI compliance, the proxied host must use version 1.2 or greater of the transport level security (TLS) protocol when protocol is set to https.

To make a proxied request in your application code, follow this pattern when constructing your request paths: /mobify/proxy/<PROXY_PATH>.

If you have lots of different proxy configurations, choose proxy paths that make it easy to recognize which APIs you’re using.

Let’s look at an example request that uses api as the <PROXY_PATH> value. By default, all projects created with PWA Kit come with a default configuration that associates the api path with the Salesforce Commerce API.

Our example request also features two helper functions to ensure that API requests work consistently:

  1. getAppOrigin (from the PWA Kit React SDK): Returns the correct origin for both local development and Managed Runtime environments.
  2. fetch (from the cross-fetch library): Handles the differences between making network requests in a browser and on the server side.

Whenever you change your proxy configuration during local development, you must restart your local development server for the changes to take effect.

Managed Runtime Environments ignore the proxy configuration settings in package.json and must be configured separately. We cover how to configure Managed Runtime environments next.

Configuring Managed Runtime Environments

You have two choices for configuring proxies for Managed Runtime Environments: using the Runtime Admin tool or using the Managed Runtime API.

Using Runtime Admin

To configure proxies for a Managed Runtime environment using our web-based admin tool, follow these steps:

  1. Log in to the Runtime Admin tool.
  2. Click your project.
  3. Click an environment.
  4. Click Environment Settings from the left navigation menu.
  5. In the Advanced section, click Edit.
  6. Under Proxy Configs, click Add New Proxy.
  7. Enter the path, protocol, and host.
  8. Repeat for up to 8 proxy configurations.
  9. Go back to the start of the Advanced section and click Update.
  10. Wait for the bundle to finish redeploying.
  11. Verify that the proxy configuration is working as expected.

Screenshot of Runtime Admin

Using the Managed Runtime API

You can also configure proxies for Managed Runtime environments programmatically using the /target endpoint of the Managed Runtime API. (The Managed Runtime API often uses the term “target” instead of “environment,” but both terms refer to the same thing.)

When creating or updating environments, the JSON request body accepts an array of proxy configuration objects from a field called ssr_proxy_configs. These proxy configuration objects are defined the same way as in package.json with host, path, and protocol (optional).

Here’s an example request that updates an environment to include a proxy configuration for the api path:

Avoiding Downtime in Production

To avoid downtime, the steps for adding or removing proxies in a production environment must be done in a specific order.

To add a proxy to a production environment:

  1. Edit the environment settings for the production environment using Runtime Admin or the Managed Runtime API. (Follow the instructions described earlier.)
  2. Add the new proxy to the environment settings and save your edits.
  3. Update your PWA Kit code to use the new proxy.
  4. Push a new bundle of your PWA Kit code to the Managed Runtime.
  5. Deploy the new bundle.

To remove a proxy from a production environment:

  1. Update your PWA Kit code to use the new proxy.
  2. Push a new bundle of your PWA Kit code to the Managed Runtime.
  3. Deploy the new bundle.
  4. Edit the environment settings for the production environment using Runtime Admin or the Managed Runtime API. (Follow the instructions described earlier.)
  5. Remove the new proxy from the environment settings and save your edits.

Overriding Proxy Configurations with Environment Variables

You can override the proxy configurations for local development in package.json by setting environment variables.

Set an environment variable called SSR_PROXY1 to override the first element in the proxyConfigs array, set one called SSR_PROXY2 to override the second element, and so on.

Here's how it works: If the environment variable SSR_PROXY1 is set to https://api-staging.example.com/api, it replaces the first element in the proxyConfigs array with the following proxy configuration object:

These environment variables are commonly used with the npm start command during local development to use different instances of the API host, such as staging or production. Here’s an example that overrides the first proxy configuration object so that the api path routes requests to a staging instance:

Looking Up the Current Proxy Configuration

After proxy settings have been configured, you can look them up in your commerce app using the utility function getProxyConfigs from the PWA Kit React SDK. For example, you can use a different client ID, depending on the environment that your code is running in:

Request and Response Modifications

When a request is routed through the proxy server, both the request and the response are both modified to make them work transparently with your application code.

The examples provided in this section assume that the app is hosted at www.northerntrailoutfitters.com and that it’s configured to proxy requests to api.commercecloud.com.

Request Modifications

The following modifications are applied to the request before sending it to the host:

  • Remove the /mobify/proxy/<PROXY_PATH>/ prefix.
  • Add an HTTP header of X-Mobify: true.

Proxied requests also forward all query string parameters and headers, including cookies.

Response Modifications

The following modifications are applied to the response before sending it to the client:

  • Add an HTTP header of X-Request-Url: <URL> with the URL that was requested.
  • If the response is a redirect and the response’s Location header whose host matches the proxy’s host, then host is prefixed with /mobify/proxy/<PROXY_PATH>/.
  • If the response contains Set-Cookie headers whose domain matches the host of the proxy, they’re updated to match it. For example, Set-Cookie: key=val; domain=api.commercecloud.com is updated to Set-Cookie: key=val; domain=www.northerntrailoutfitters.com.
  • If the response contains an Access-Control-Allow-Origin header whose value matches the proxy’s host, it’s updated to Access-Control-Allow-Origin: https://www.northerntrailoutfitters.com.

To test your modifications, configure a proxy configuration with httpbin.org as the host. When you make a request to through that proxy, it echoes back any headers that it receives.

Improving Proxy Performance with Caching

By default, proxied requests are uncached by the CDN. This default allows proxies requests to be used transparently in your code, without having to worry about incorrectly caching responses.

When you do want a proxied request to be cached by the CDN, change the path prefix used in your request from proxy to caching:

Caching Details

Cached proxy requests differ from standard proxy requests in the following way:

  • The Cookie HTTP header is removed.

Cached responses differ from standard responses in the following way:

  • Any Set-Cookie HTTP headers are removed.

Cached responses include the following HTTP headers so that when the values of these headers vary, the responses are cached separately:

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Authorization
  • Range

Responses that include other HTTP headers are not cached separately when their values vary.

Next Steps

Now that you understand how and why to use proxies in your commerce app, keep exploring the PWA Kit documentation.