Perform HTTP Requests
This guide explains how to execute arbitrary HTTP requests using the SAP Cloud SDK for JavaScript. The HTTP client provided by the SAP Cloud SDK provides some convenience features which are explained in detail in this guide.
If you want to use an OData API, please refer to the Executing a request using a generated OData client page. In case you want to use an OpenAPI client, please refer to the Execute a Request Using a Generated OpenAPI Client page.
When to Use What?
The SAP Cloud SDK for JavaScript can generate clients for OData and OpenAPI. Use generated clients for OData or OpenAPI services, if possible.
Generated clients provide convenience features such as:
- Type-safe response objects
- Convenient handling of filter, select and expand conditions
- Built-in
ETag
versions handling
Be sure to check if the clients for OData or OpenAPI support your use case.
For example, the OData client does not support the upsert
operation.
The generic HTTP client is based on the open-source axios HTTP client, but provides convenience features which are specific to working on SAP Business Technology Platform, such as:
- Destination lookup
- Connections to SAP S/4HANA On-Premise via the connectivity service
- Web proxies
executeHttpRequest
The most basic way to use the SAP Cloud SDK HTTP client is the function executeHttpRequest.
executeHttpRequest(destination, requestConfig, httpRequestOptions): Promise<HttpResponse>;
This guide provides code snippets, fully executable example code can be found in the SAP-samples/cloud-sdk-js repository on GitHub.
In the most simple form, this can be invoked like this:
const response = await executeHttpRequest(
{
url: 'https://example.com'
},
{
method: 'get'
}
);
The executeHttpRequest()
function takes the following parameters:
- The
destination
argument is of typeDestinationOrFetchOptions
- This can either be a destination object which was already fetched or an object containing a destination name and an optional JWT
- The
requestConfig
argument is of type HttpRequestConfig or HttpRequestConfigWithOrigin - The
httpRequestOptions
argument is of typeHttpRequestOptions
- This parameter is optional
- Can be used to disable automatic CSRF token fetching
Note that the destination
and requestConfig
parameters have an overlap in the keys they accept.
For example, both have a url
and an authorization
property.
For keys that exist for both objects, the requestConfig
takes precedence.
The executeHttpRequest()
function returns a promise of type HttpResponse.
CSRF Token Fetching
Cross-Site Request Forgery (CSRF) is a common type of attack on web applications. The HTTP client provided by SAP Cloud SDK allows to automatically retrieve a CSRF token for HTTP APIs which support this.
Fetching CSRF token is automatically enabled for all requests that typically might change data, such as PUT
, POST
, DELETE
, or PATCH
requests.
It is not available for GET
requests.
Fetching the CSRF token can be enabled or disabled via the httpRequestOptions.fetchCsrfToken
parameter of executeHttpRequest()
function.
See its API documentation for details.
For example, to avoid CSRF token fetching when doing a PUT
, POST
, DELETE
, or PATCH
request, disable it like in this example:
const response = await executeHttpRequest(
{
url: `https://example.com`
},
{
method: 'post'
},
{
fetchCsrfToken: false
}
);
Parameter Encoding
URL encoding allows using characters as part of the URL which normally would cause issues such as spaces.
For example, the space character is replaced with %20
.
The HTTP client automatically takes care of encoding parameters except for custom parameters. Custom parameters can be useful when you need control exactly how values are transmitted to the backend system.
Customized Parameter Encoding
If you need to customize parameter encoding, you can provide your own function to do the transformation. This feature is meant for cases where backends have special requirements for the encoding that don't work with the default URL-encoding done by the HTTP client. You should usually avoid this as it adds additional complexity to the application code.
The example below shows how to do a string replace:
const myCustomParameterEncodingFunction: ParameterEncoder = function (
params: Record<string, any>
): Record<string, any> {
const encodedParams: Record<string, any> = {};
for (const key in params) {
// Customize your required encoding logic here
encodedParams[key] = params[key].toString().replace('x', 'y');
}
return encodedParams;
};
const response = await executeHttpRequest(
{
url: 'https://example.com'
},
{
method: 'get',
params: {
param1: 'a/bx',
param2: 'x1'
},
// Pass your custom encoding function
parameterEncoder: myCustomParameterEncodingFunction
}
);
The HTTP request in this example will contain the parameter values a/by
and y1
because our parameter encoder function replaced the x
with a y
.
executeHttpRequestWithOrigin()
The executeHttpRequestWithOrigin()
function is a variation of executeHttpRequest()
which allows more fine-grained control over configuration precedence.
The term "origin" as it is used in the context of this guide does not refer to a URL as in the "same-origin policy". Instead it refers to the origin or source of HTTP client configuration.
This function may be helpful in situations where you want to define the priority of headers and parameters, for example if:
- You want to enforce a hard-coded API key or JWT and ignore the ones from the destination
- You want a default query parameter, which can be overwritten by the destination properties
Headers and query parameters with the same name are prioritized in the following order:
custom
- Destination related headers/query parameters
requestConfig
In this example the HTTP request will contain the URL parameter myParam
with the value custom-param
and the HTTP header apiKey
with the value custom-header
:
const response = await executeHttpRequestWithOrigin(
{
url: 'https://example.com'
},
{
method: 'get',
headers: {
custom: { apiKey: 'custom-header' },
requestConfig: { apiKey: 'default-header' }
},
params: {
custom: { myParam: 'custom-param' },
requestConfig: { myParam: 'default-param' }
}
}
);