Show TOC

Step 26: Remote OData ServiceLocate this document in the navigation structure

So far we have only worked with local JSON data, but now we will access a real OData service. Instead of implementing an own OData service we will simply use the publicly available Northwind OData service to visualize remote data. You will be surprised how little needs to be changed in order to make this work!

Preview
Figure 1: Products from the OData invoices test service are now shown within our app
Coding

You can view and download all files in the Explored app in the Demo Kit under Walkthrough - Step 26.

webapp/manifest.json
{
  "_version": "1.1.0",
  "sap.app": {
	...
	"ach": "CA-UI5-DOC",
	"dataSources": {
	  "invoiceRemote": {
		"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/",
		"type": "OData",
		"settings": {
		  "odataVersion": "2.0"
		}
	  }
	}
  },
  "sap.ui": {
	...
  },
  "sap.ui5": {
	"_version": "1.1.0",
	"rootView": "sap.ui.demo.wt.view.App",
	"dependencies": {
	  "minUI5Version": "1.30",
	  "libs": {
		"sap.m": {}
	  }
	},
	"models": {
	  "i18n": {
		"type": "sap.ui.model.resource.ResourceModel",
		"settings": {
		  "bundleName": "sap.ui.demo.wt.i18n.i18n"
		}
	  },
	  "invoice": {
		"dataSource": "invoiceRemote"
	  }
	}
  }
}

In the sap.app section of the descriptor file, we add a data source configuration. With the invoiceRemote, key we specify a configuration object that allows automatic model instantiation. We specify the type of the service (OData) and the model version (2.0). In this step, we want to use the publicly available Northwind OData service located at https://services.odata.org/V2/Northwind/Northwind.svc/. Therefore, the URI points to the official Northwind OData service.

Note

We are referencing the Northwind OData service via HTTPS. However, the certificate might not be trusted. Thus, make sure that you call the URL https://services.odata.org/V2/Northwind/Northwind.svc/ directly in your browser and accept the certificate once, before you continue.

In the models section, we replace the content of the invoice model. This key is still used as model name when the model is automatically instantiated during the component initialization. However, the invoiceRemote value of the dataSource key is a reference to the data source section that we specified above. This configuration allows the component to retrieve the technical information for this model during the start-up of the app.

Our component now automatically creates an instance of sap.ui.model.odata.v2.ODataModel according to the settings we specified above, and makes it available as model named invoice. If you want to have a default model on the component, you can change the name of the model to an empty string in the descriptor file. Automatically instantiated models can be retrieved by calling this.getModel in the component. In the controllers of component-based apps you can call this.getView().getModel() to get the automatically instantiated model. For retrieving a named model you have to pass on the model name defined in the descriptor file to getModel, this means, in the component you would call this.getModel("invoice") to get our automatically generated invoice model that we defined in the descriptor.

When using the data source invoiceRemote, the ODataModel fetches the data from the real Northwind OData service. The invoices we receive from the Northwind OData service have identical properties as the JSON data we used previously (except for the status propertythat is not available in the Northwind OData service).

You can now try to run the app and see what happens - we will see some errors in the browser’s console:

Figure 2: Violations of the same-origin policy in Google Chrome
Note

Due to the so called same-origin policy, browsers deny AJAX requests to service endpoints in case the domain/subdomain, protocol, or port differ from the app’s domain/subdomain, protocol, or port.

The browser refuses to connect to a remote URL directly for security reasons and we need a workaround.

For productive apps this approach is not recommended – we will describe the options later in this step.

Tip

In Google Chrome, you can easily disable same-origin policy of Chrome by running Chrome with the following command: [here-your-path-to-chrome-installation-dir]\chrome.exe --disable-web-security. Make sure that all instances of Chrome are closed before you run the command above. This will allow all Web sites to break out of the same-origin policy and connect to the remote service directly. Be aware that it’s a security risk in case you run Chrome this way for surfing on the internet. However, it also allows you to avoid the need of setting up a proxy at development time or for testing purposes

After disabling the same-origin policy in your browser, you can now run the app again. This time you can see all kinds of invoices retrieved from a real back end. In case you still have issues, just continue with the next step. There, we will switch to local mock data.

Note

In the component, we have added a dependency to sap.ui.model.odata.v2.ODataModel. The v2 in the namespace stands for the second version of the ODataModel implementation in SAPUI5. This v2 is not related to the "OData Version 2" specification. We recommend suggested to use the new implementation sap.ui.model.odata.v2.ODataModel instead of the old sap.ui.model.odata.ODataModel in your SAPUI5 apps.

Optional: Proxy Configuration to Avoid Same-Origin Policy Issues

In a real app scenario, the remote system would be configured to send the cross-origin resource sharing (CORS) headers to make the browser also allow direct access to remote URLs. However, we cannot modify the publicly available Northwind OData service. Thus, when trying to execute XHR requests (XMLHttpRequest) the browser will prevent the call due to the so called same-origin policy as we have experienced above.

In order to overcome these issues, we have the following options:
  • Deploy the app on the same server or domain as the service we want to call, so that both resources are in the same origin

  • Set the CORS-relevant response headers on the remote system

  • Use a helper service from the same domain of our app as a proxy to call the real remote service

  • Disable same-origin policy in the browser for local testing

In the previous section we used the last approach which is not recommended for productive scenarios.

We will now switch to using a helper service as a proxy. For us, a proxy is simply a service end point on the same domain of our app to overcome the restrictions described above. It receives requests from our app, forwards them to another server, and finally returns the corresponding response from the remote service.

SAP Web IDE and the SAP HANA Cloud Platform offer so-called destinations that allow to easily connect to remote systems. The destination to our Northwind OData service is an internet proxy made available inside the app at <protocol>://<domain>/destinations/northwind/*. Any request that is sent to this location will be forwarded to http://services.odata.org automatically.

Here are a few examples:
Table 1: Examples for requests

Requested URL

Forwarded To

/destinations/northwind/V2/Northwind/Northwind.svc/$metadata

http://services.odata.org/V2/Northwind/Northwind.svc/$metadata

/destinations/northwind/V2/Northwind/Northwind.svc/Invoices

http://services.odata.org/V2/Northwind/Northwind.svc/Invoices

The destination itself is configured inside the SAP HANA Cloud Platform Cockpit. To set up the destination for the Northwind OData service follow the configuration steps described under Create a Northwind Destination.

In the following, we describe how to use the destination in our app to connect to the Northwind OData service.

Note

This section is describing the setup for the SAP Web IDE only. If you are using a different development environment, you can either create a simple proxy service by yourself or use an existing one.

neo-app.json for SAP Web IDE (new)
{
  "routes": [
    {
      "path": "/destinations/northwind",
      "target": {
        "type": "destination",
        "name": "northwind"
      },
      "description": "Northwind OData Service"
    }
  ]
}

The neo-app.json file is needed for SAP Web IDE to make sure that the destination and the resource mapping are available in the app. It has to be located in the root folder (webapp), on the same level as the user.project.json file that is automatically created.

If it does not exist yet, create the file and reference the Northwind destination there. Just copy the content of the code block above into that file and try to run the app again.

Note

If the file already exists, for example, because you already created it to map the SAPUI5 resources as described in Step 2 of this tutorial, just append the destination to the existing route definitions.

Now you can run the app even without disabling the same-origin policy in your browser. In other words, the app can be used by any user even without changing the browser settings.

webapp/manifest.json
{
  "_version": "1.1.0",
  "sap.app": {
	...
	"dataSources": {
	  "invoiceRemote": {

		"uri": "/destinations/northwind/V2/Northwind/Northwind.svc/",
		"type": "OData",
		"settings": {
		  "odataVersion": "2.0"
		}
	  }
	}
  },
  "sap.ui": {
	...
  },
  "sap.ui5": {
	...
  }
}

In the descriptor file, we change the invoiceRemote data source to use the Northwind destination. After this change, you can run the app in the SAP Web IDE even without disabling the same-origin policy of your browser. The destination now manages the connection to the remote service.