Service¶
This is a .service file that defines an OData Service destination. The DestinationName property is used as the suffix to the ServerUrl URL when queries are made using this service.
A service can run in an online or offline mode.
To configure a service for online mode, set the OfflineEnabled in the .service file to false. In this case, the MDK client communicates directly with the OData service. You can configure your apps to perform reads and updates to synchronize the client data.
To configure a service for offline mode, set the OfflineEnabled in the .service file to true. In this case, the MDK client communicates with the OData service via the offline OData provider. You can configure your apps to initialize a data store and synchronize it with the OData service.
Service Properties¶
| Property | Type | Required | Default |
|---|---|---|---|
| DestinationName | string |
Yes | |
| Headers | object |
No | |
| LanguageURLParam | string |
No | |
| OfflineEnabled | boolean |
No | true |
| OfflineOptions | object |
No | |
| OnOfflineProgressUpdate | Rule | No | |
| OnlineOptions | object |
No | |
| PathSuffix | string |
No | |
| RestService | boolean |
No | false |
| ServiceUrl | string |
Yes |
DestinationName¶
The destination name of the OData service in the Mobile Services
- type:
string
Headers¶
Custom headers to be included in all OData requests for the service in key/value pair format. If additional custom headers are defined in an OData action or an OData function in ClientAPI, the service headers merge to the custom headers in the OData action or OData function in ClientAPI.
If you are deploying the WebClient App on the NEO environment and you need additional HTTP headers to be forwarded to or from a backend request or backend response, add the header names in the following format to the Config.js file:
e.g.
"headerWhiteList": ["APIKey"]
For more information, see this.
- type:
object
LanguageURLParam¶
Indicates if this service can accept requests with language parameter
- type:
string
OfflineEnabled¶
Indicates if this service runs in offline mode. This is set to false for WebClient.
-
type:
boolean -
default:
true
OfflineOptions¶
Additional options for the service if OfflineEnabled is set to true.
- type:
objectwith following properties.
| Property | Type | Required | Default |
|---|---|---|---|
ServiceOptions |
OfflineServiceOptions | No | |
CSDLOptions |
CSDLOptions | No | |
StoreParameters |
StoreParameters | No | |
ProgressMessages |
ProgressMessages | No | |
AutoIncludeProgressMessages |
boolean | No | true |
ServiceOptions¶
Offline options for interaction with a data service.
CSDLOptions¶
Options for CSDL Parser
StoreParameters¶
Offline store OData parameters
ProgressMessages¶
Defines custom format strings for each offline OData operation step. When provided, these override the default localized progress messages displayed during offline operations, like open, download, upload, send store. Each step name maps to a format string that supports placeholders: {0} for current step number, {1} for total steps, {2} and {3} for step-specific parameters (e.g., bytes transferred, request name). If both ProgressMessages and action-level ProgressText are defined, ProgressMessages takes priority.
AutoIncludeProgressMessages¶
Controls whether progress messages are automatically displayed in the ActivityIndicator and Banner UI components during offline OData operations. When set to true (default), progress messages from ProgressMessages, ProgressText, or built-in defaults are shown automatically. When set to false, no progress text or messages appear, regardless of the customization in ProgressText and ProgressMessages. The OnOfflineProgressUpdate rule is still invoked when defined, but the returned message is not auto-displayed.
OnlineOptions¶
Additional options for the service if OfflineEnabled is set to false.
- type:
objectwith following properties.
| Property | Type | Required | Default |
|---|---|---|---|
ServiceOptions |
OnlineServiceOptions | No | |
CSDLOptions |
CSDLOptions | No |
ServiceOptions¶
Online options for interaction with a data service.
CSDLOptions¶
Options for CSDL Parser
OnOfflineProgressUpdate¶
Specifies a .js rule file called on each progress update during offline OData operations (open, download, upload, send store). The rule accesses progress details, such as the current step, step number, and message via context.getEventData(). The rule returns a string for customizing the displayed message, or a Promise<string> for asynchronous processing. Whether the returned message is automatically shown in the UI depends on the AutoIncludeProgressMessages setting.
- type: Rule
- default:
""
PathSuffix¶
The path suffix that will be appended to the DestinationName and used to initialize the Online Service or Offline store. If OfflineEnabled is set to true, then you must also set OfflineOptions > StoreParameters > StoreName.
- type:
string
RestService¶
Indicates whether this service is a REST service.
-
type:
boolean -
default:
false
ServiceUrl¶
URL to the OData service (deprecated). Service URL will now be taken from the ServerUrl in brandedSettings.json or overrides.json or Onboarding URL.
- type:
string
Examples¶
Service with LanguageURLParam & Headers¶
{
"DestinationName": "Northwind",
"OfflineEnabled": true,
"LanguageURLParam": "sap-language",
"Headers": {
"Accept-Language": "/MyMDKApp/Rules/GetLanguage.js"
}
}
Service with PathSuffix¶
{
"DestinationName":"Northwind",
"PathSuffix":"/V3/OData/OData.svc",
"OfflineEnabled": true,
"OfflineOptions": {
"StoreParameters": {
"StoreName": "NorthwindV3"
}
}
}
Offline Service With CSDL Options and Store Parameters¶
{
"DestinationName":"Northwind",
"OfflineEnabled": true,
"OfflineOptions": {
"ServiceOptions": {
"supportsBind": false,
"supportsPatch": false,
},
"CSDLOptions": [
"allowCaseConflicts",
"defaultVariableScale",
"defaultVariableSrid",
"disableFacetWarnings",
"disableLoggingOfErrors",
"disableLoggingOfWarnings",
"disableNameValidation",
"excludeServerOnlyElements",
"failIfProviderIncompatible",
"ignoreAllAnnotations",
"ignoreAllReferences",
"ignoreEdmAnnotations",
"ignoreExternalReferences",
"ignoreInternalReferences",
"ignoreStandardReferences",
"ignoreUndefinedTerms",
"ignoreXmlAnnotations",
"logWithUnqualifiedFileNames",
"processMixedVersions",
"resolveUndefinedTerms",
"retainOriginalText",
"retainResolvedText",
"traceParsingOfElements",
"strictFacetWarnings",
"warnAboutUndefinedTerms",
"warnIfProviderIncompatible"
],
"StoreParameters": {
"EnableIndividualErrorArchiveDeletion": true,
"EnableRepeatableRequests": true
}
}
}
Online Service with Service Options & CSDL Options¶
{
"DestinationName":"Northwind",
"OfflineEnabled": false,
"OnlineOptions": {
"ServiceOptions": {
"avoidInPaths": "test",
"cacheMetadata": false,
"checkQueries": false,
"checkResults": false,
"checkVersion": false,
"dataFormat": 1,
"dataVersion": 0,
"databaseOnly": false,
"fixMissingEmptyLists": false,
"fixMissingNullValues": false,
"logErrors": false,
"logWarnings": false,
"metadataFile": "test",
"metadataText": "test",
"metadataURL": "/Test/$metadata",
"pingAccept": "application/json",
"pingMethod": "GET",
"pingResource": "/",
"requiresToken": "X-CSRF-Token",
"requiresType": false,
"supportsAlias": false,
"supportsBatch": false,
"supportsBind": false,
"supportsDelta": false,
"supportsNext": false,
"supportsPatch": false,
"supportsUnbind": false,
"statefulService": false
},
"CSDLOptions": [
"allowCaseConflicts",
"defaultVariableScale",
"defaultVariableSrid",
"disableFacetWarnings",
"disableLoggingOfErrors",
"disableLoggingOfWarnings",
"disableNameValidation",
"excludeServerOnlyElements",
"failIfProviderIncompatible",
"ignoreAllAnnotations",
"ignoreAllReferences",
"ignoreEdmAnnotations",
"ignoreExternalReferences",
"ignoreInternalReferences",
"ignoreStandardReferences",
"ignoreUndefinedTerms",
"ignoreXmlAnnotations",
"logWithUnqualifiedFileNames",
"processMixedVersions",
"resolveUndefinedTerms",
"retainOriginalText",
"retainResolvedText",
"traceParsingOfElements",
"strictFacetWarnings",
"warnAboutUndefinedTerms",
"warnIfProviderIncompatible"
]
}
}
Rest Service¶
OfflineEnabled must be set to false when RestService is true
{
"DestinationName":"Northwind",
"OfflineEnabled": false,
"RestService": true
}
Offline Service with Custom ProgressMessages¶
Defines custom step-level progress messages with format string placeholders for each offline OData operation step.
{
"DestinationName": "Northwind",
"OfflineEnabled": true,
"OfflineOptions": {
"ProgressMessages": {
"BuildingEntityStore": "{0}/{1} Building the entity store...",
"CreatingBootStrapDatabase": "{0}/{1} Creating bootstrap database...",
"CreatingRequestQueueDatabase": "{0}/{1} Creating request queue database...",
"DownloadingEntityStore": "{0}/{1} Downloading entity store... {2}",
"ErasingExpiredRequests": "{0}/{1} Erasing expired requests...",
"LoadingMetadata": "{0}/{1} Loading metadata...",
"PerformingTransactionMerge": "{0}/{1} Performing transaction merge...",
"PerformingCreateDeleteMerge": "{0}/{1} Performing create-delete merge...",
"ProcessingDefiningQueries": "{0}/{1} Processing defining queries... {2}",
"ProcessingRequests": "{0}/{1} Processing requests... {2}",
"ReapplyingChanges": "{0}/{1} Reapplying changes...",
"AnalyzingReceivedData": "{0}/{1} Analyzing received data...",
"ReceivingDataFromServer": "{0}/{1} Receiving data from server... {2}",
"RemovingDeletedRelationships": "{0}/{1} Removing deleted relationships...",
"RemovingRemoveAfterUploadRequests": "{0}/{1} Removing RemoveAfterUpload requests...",
"SendingDataToServer": "{0}/{1} Sending data to server... {2}",
"SendingEntityStoreDatabase": "{0}/{1} Sending entity store... {2}/{3}",
"SendingRequestQueueDatabase": "{0}/{1} Sending request queue database...",
"UploadPreprocessing": "{0}/{1} Pre-processing before uploading...",
"WaitingForDownload": "{0}/{1} Waiting for download..."
}
}
}
Offline Service with Custom Localized ProgressMessages using i18n¶
By default, the MDK client provides built-in localized progress messages, no configuration is required. To customize these messages with localization, the ProgressMessages values support the $(L, key) localization syntax. The keys are resolved at runtime from the project's i18n/i18n.properties files, enabling multi-language support without a custom rule.
{
"DestinationName": "Northwind",
"OfflineEnabled": true,
"OfflineOptions": {
"ProgressMessages": {
"BuildingEntityStore": "{0}/{1} $(L, buildingEntityStore)",
"CreatingBootStrapDatabase": "{0}/{1} $(L, creatingBootStrapDatabase)",
"CreatingRequestQueueDatabase": "{0}/{1} $(L, creatingRequestQueueDatabase)",
"DownloadingEntityStore": "{0}/{1} $(L, downloadingEntityStore) {2}",
"ErasingExpiredRequests": "{0}/{1} $(L, erasingExpiredRequests)",
"LoadingMetadata": "{0}/{1} $(L, loadingMetadata)",
"PerformingTransactionMerge": "{0}/{1} $(L, performingTransactionMerge)",
"PerformingCreateDeleteMerge": "{0}/{1} $(L, performingCreateDeleteMerge)",
"ProcessingDefiningQueries": "{0}/{1} $(L, processingDefiningQueries) {2}",
"ProcessingRequests": "{0}/{1} $(L, processingRequests) {2}",
"ReapplyingChanges": "{0}/{1} $(L, reapplyingChanges)",
"AnalyzingReceivedData": "{0}/{1} $(L, analyzingReceivedData)",
"ReceivingDataFromServer": "{0}/{1} $(L, receivingDataFromServer) {2}",
"RemovingDeletedRelationships": "{0}/{1} $(L, removingDeletedRelationships)",
"RemovingRemoveAfterUploadRequests": "{0}/{1} $(L, removingRemoveAfterUploadRequests)",
"SendingDataToServer": "{0}/{1} $(L, sendingDataToServer) {2}",
"SendingEntityStoreDatabase": "{0}/{1} $(L, sendingEntityStoreDatabase) {2}/{3}",
"SendingRequestQueueDatabase": "{0}/{1} $(L, sendingRequestQueueDatabase)",
"UploadPreprocessing": "{0}/{1} $(L, uploadPreprocessing)",
"WaitingForDownload": "{0}/{1} $(L, waitingForDownload)"
}
}
}
With the corresponding i18n/i18n.properties:
buildingEntityStore=Building the entity store
creatingBootStrapDatabase=Creating bootstrap database
creatingRequestQueueDatabase=Creating request queue database
downloadingEntityStore=Downloading entity store
erasingExpiredRequests=Erasing expired requests
loadingMetadata=Loading metadata
performingTransactionMerge=Performing transaction merge
performingCreateDeleteMerge=Performing create-delete merge
processingDefiningQueries=Processing defining queries
processingRequests=Processing requests
reapplyingChanges=Reapplying changes
analyzingReceivedData=Analyzing received data
receivingDataFromServer=Receiving data from the server
removingDeletedRelationships=Removing deleted relationships
removingRemoveAfterUploadRequests=Removing RemoveAfterUpload requests
sendingDataToServer=Sending data to the server
sendingEntityStoreDatabase=Sending entity store database
sendingRequestQueueDatabase=Sending request queue database
uploadPreprocessing=Pre-processing requests before uploading
waitingForDownload=Waiting for download
Offline Service with OnOfflineProgressUpdate Callback¶
A rule is invoked for every progress update during offline operations.
{
"DestinationName": "Northwind",
"OfflineEnabled": true,
"OnOfflineProgressUpdate": "/MyMDKApp/Rules/OnOfflineProgressUpdate.js"
}
OnOfflineProgressUpdate Rule — Synchronous¶
This rule receives progress data through context.getEventData() and returns a custom message string. If AutoIncludeProgressMessages is set to true, this custom message string replaces the UI default progress message.
Available eventData properties include: eventName, step, currentStepNumber, totalStep, message, messageParam1, messageParam2.
// OnOfflineProgressUpdate.js
export default function OnOfflineProgressUpdate(context) {
const eventData = context.getEventData();
const currentStepNumber = eventData.currentStepNumber;
const totalStep = eventData.totalStep;
const messageParam1 = eventData.messageParam1;
const messageParam2 = eventData.messageParam2;
let customMessage = eventData.message;
switch (eventData.step) {
case "BuildingEntityStore":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('buildingEntityStore')}`;
break;
case "DownloadingEntityStore":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('downloadingEntityStore')} ${messageParam1}`;
break;
case "ProcessingDefiningQueries":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('processingDefiningQueries')} ${messageParam1}`;
break;
case "ReceivingDataFromServer":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('receivingDataFromServer')} ${messageParam1}`;
break;
case "SendingDataToServer":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('sendingDataToServer')} ${messageParam1}`;
break;
case "SendingEntityStoreDatabase":
customMessage = `${currentStepNumber}/${totalStep} ${context.localizeText('sendingEntityStoreDatabase')} ${messageParam1}/${messageParam2}`;
break;
// Other steps: return default message
}
return customMessage;
}
OnOfflineProgressUpdate Rule — Asynchronous (Promise)¶
When the rule returns a Promise, the offline operation continues without blocking. The resolved message is pushed to the UI asynchronously. This approach is useful for updating page controls or performing other asynchronous tasks.
// OnOfflineProgressPromiseUpdate.js
export default function OnOfflineProgressUpdate(context) {
const eventData = context.getEventData();
// Access page controls to display progress details
const pageProxy = context.evaluateTargetPathForAPI('#Page:ProgressPage');
const section = pageProxy.getControl('SectionedTable').getSection('ProgressSection');
const stepControl = section.getControl('Step');
const messageControl = section.getControl('Message');
const customMessage = `${eventData.currentStepNumber}/${eventData.totalStep} ${eventData.step}`;
// Update page controls, then resolve with the display message
stepControl.setValue(eventData.step);
return messageControl.setText(customMessage).then(() => {
return customMessage;
});
}
Offline Service with AutoIncludeProgressMessages Disabled¶
When AutoIncludeProgressMessages is set to false, progress text or messages are not injected into the ActivityIndicator or Banner UI, regardless of ProgressText or ProgressMessages customization. The OnOfflineProgressUpdate rule is still invoked, but the returned message is not auto-displayed.
{
"DestinationName": "Northwind",
"OfflineEnabled": true,
"OfflineOptions": {
"AutoIncludeProgressMessages": false
},
"OnOfflineProgressUpdate": "/MyMDKApp/Rules/OnOfflineProgressUpdate.js"
}
Progress Resolution Behavior¶
The following table shows how ProgressText (action-level), ProgressMessages (service-level), and AutoIncludeProgressMessages interact to determine the content displayed during offline OData operations:
| ProgressText | ProgressMessages | AutoIncludeProgressMessages | Result |
|---|---|---|---|
| Not defined | Not defined | true |
Default ProgressMessages |
| Not defined | Defined | true |
Custom ProgressMessages |
| Defined | Not defined | true |
Custom ProgressText |
| Defined | Defined | true |
Custom ProgressMessages |
| Not defined | Not defined | false |
No progress text or messages injected |
| Not defined | Defined | false |
No progress text or messages injected |
| Defined | Not defined | false |
No progress text or messages injected |
| Defined | Defined | false |
No progress text or messages injected |
Notes:
-
AutoIncludeProgressMessages: falsedisables all automatic progress UI updates, regardless ofProgressTextorProgressMessagessettings. -
ProgressMessagestakes precedence overProgressTextwhen both are defined. -
ProgressMessagesreplaces the legacy defaultProgressText, offering more comprehensive step-level reporting. To retain the previous behavior, explicitly define customProgressTextvalues.
ServiceUrl (Deprecated)¶
If DestinationName is not specified, the destination name will be taken from the ServiceUrl property. This is done by taking the last path component from the URL.
{
"ServiceUrl":"https://mobile-w00070145a18.eu2.hana.ondemand.com/com.sap.sam.swa",
"OfflineEnabled": true,
"LanguageURLParam": "sap-language"
}