Executing a Request Using a Generated OData v2/v4 Client
Once you have generated a typed OData client using the SAP Cloud SDK generator or if you decided to use one of the pregenerated OData clients for SAP S/4HANA, you can use your OData client to execute HTTP requests against your service. The client provides request builders for the different types of requests and abstractions of the entity sets of the given service, which we refer to as entities.
To request an entity set, entities offer a fluent API.
General Request Structure
On an abstract level, creating a request using the fluent API always follows the same simple structure:
import { MyEntity } from './outputDir/my-service';
return MyEntity.requestBuilder()
.<requestType>(...)
.<additionalRequestConfiguration>(...)
.execute(destination);
If you are using an OData client, that you generated on your own, import an entity from the generated service directory (my-service
) within the specified output directory (outputDir
).
The name of the service directory corresponds to the directoryName
specified in the service mapping file (serviceMapping.json
by default) in your input directory.
If you are using one of the pregenerated OData clients, import it from the npm package.
import { PregeneratedEntity } from '@sap/cloud-sdk-vdm-pregenerated-service';
Every entity has a requestBuilder
function, that allows to chain all types of request builders that are available for this entity, e.g. MyEntity.requestBuilder().getAll()
for the getAll
request type.
See the list below for details on all available request types (denoted by requestType
in the example above):
- OData v2
- OData v4
Some entities do not support all the request types, which in turn won't be available through the API.
The request can further be configured by chaining additional configuration functions (denoted by additionalRequestConfiguration
in the example above).
All requests can be configured by setting custom request headers, custom query parameters and a custom service path.
Each request type has additional request specific configuration options, e.g. creating an entity asChildOf
another entity for create
requests, ETag handling for update
and delete
requests, as well as set operations for getAll
requests and selecting properties for getAll
and getByKey
requests.
The last step when making a request using the SAP Cloud SDK is the request execution.
Once the request is configured use the execute
function and pass a destination to it.
This will automatically construct your request URL and headers, execute the request, and return a typed response if applicable.
Setting Custom Request Headers
The SAP Cloud SDK automatically sets some necessary request headers on every request.
You can specify additional custom headers using the addCustomHeaders
function:
MyEntity.requestBuilder().getAll().addCustomHeaders({
apikey: 'my-api-key'
});
The keys and values of the passed object correspond with the header names and values.
Custom headers take priority over automatically generated headers.
Automatically generated headers are sent with lowercase header names, and custom headers keep the case they were set in.
In the example above we pass an apikey
, which is necessary if you want to make use of the SAP Business Accelerator Hub sandbox.
Setting an authorization
or apikey
header (regardless of lowercase or uppercase spelling) will skip any automatic authorization header building that the SAP Cloud SDK would normally do.
Setting Custom Query Parameters
The SAP Cloud SDK adds necessary query parameters for a request based on your configuration.
You can add custom parameters by using the withCustomQueryParameters
function.
Custom query parameters take precedence over those created by the SAP Cloud SDK.
In the example below an additional query parameter language=en
will be added to the request URL:
MyEntity.requestBuilder().getAll().withCustomQueryParameters({
language: 'en'
});
If you want to set a query parameter in quotes (e.g. language='en'
) you will have to provide the parameter with quotes, e.g. { language: "'en'" }
.
Setting a Custom Service Path
If a service specification contains a specification for the servicePath
, the SAP Cloud SDK generator generates an OData client with a default service path according to the specification (typically '/sap/opus/data/sap/'
for SAP S/4HANA services).
When there is no such path defined in the specification, it can be manually set in the service-mapping.json
.
It can also be adjusted per request by using the withCustomServicePath
function:
MyEntity.requestBuilder()
.getAll()
.withCustomServicePath('my/custom/service/path');
This will add the custom service path to your request.
Executing the example request above against a destination with URL https://my.s4-system.com
would result in a request against something like this: https://my.s4-system.com/my/custom/service/path/MyEntity
.
Setting a Custom Request Configuration
By default, the SAP Cloud SDK uses axios as an HTTP client for executing requests.
The SAP Cloud SDK derives and configures most request options like url
, headers
, and others for you.
In certain cases, passing additional options to axios might be required.
To achieve this, you can provide a custom request configuration that will be passed down to axios.
The example below demonstrates how to configure the response data type, typically used when downloading a file from an endpoint.
MyEntity.requestBuilder()
.getAll()
.addCustomRequestConfiguration({ responseType: 'arraybuffer' });
To ensure API consistency, we do not allow overriding the following options:
method
url
baseURL
data
headers
params
Appending Paths to the Request URL Built by the Request Builders
Usually, our request builders construct the request URL for you automatically.
However, for certain OData features like navigation properties
, we do not yet provide a type-safe API that constructs the request path in a fully automated manner.
For that reason, we added a non-typed API to our request builders providing the capability to append additional path segments to the request URL.
You have to use the executeRaw(destination)
method to get results because we can't deserialize a response in a type-safe way.
The example below shows how to query a navigation property from a given entity.
MyEntity.requestBuilder()
.getByKey('123')
.appendPath(
'/to_SingleValueNavigationProperty1',
'/to_SingleValueNavigationProperty2'
)
.executeRaw(destination);
It will build the request URL like below:
https://my.s4-system.com/service-path/MyEntity(key='123')/to_SingleValueNavigationProperty1/to_SingleValueNavigationProperty2
where:
/to_SingleValueNavigationProperty1/to_SingleValueNavigationProperty2
is the additional path that you provide from the parameters.https://my.s4-system.com/service-path/MyEntity(key='123')
is the path of the original request URL built by the SAP Cloud SDK.
Getting the Raw Response and the Original Request
In addition to the execute
method, you can execute a request using the executeRaw
method.
It returns an HttpResponse
, which contains the following properties:
status
- the status code of the responseheaders
- the response headersdata
- the response bodyrequest
- the original request
Example:
const httpResponse: HttpResponse = MyEntity.requestBuilder()
.getAll()
.executeRaw(destination);
Typical cases, where you might need to use executeRaw
are:
- You need additional information about the response, like the status code or response headers.
- You need additional information about the request that has been sent, like payload, method, or request headers.
- The function
execute
is omitted in some request builders because the response data cannot be deserialized by the request builder. - Debugging purposes.
In rare cases, when the response data cannot be deserialized. This can happen when function imports use an entity type as a return type, and this entity type is shared by multiple
EntitySet
s. Without further information, it is unclear whichEntity
should be deserialized. For those cases, you have to useexecuteRaw
and use thedeserialize
function on the response data.