Forwarding local AJAX requests to an SAP ABAP server with Nginx

I am busy doing a little proof-of-concept solution to produce a mobile app using a BSP application as a container. In concept, this sounds easy, but there are always snags that slow down the development process, particularly trying to test AJAX calls to a remote server from a locally hosted app.

Testing AJAX calls to a server when developing a web app locally on your machine is problematic due to cross-domain security constraints. At the previous client where I worked, I got around this by using JSONP when hosting the application locally, which introduced other problems, specifically catching failures in these calls.

A way to properly test your application locally with JSON calls is to run a local web server and set it up as a reverse proxy, thus forwarding all requests to certain URIs to the remote server where the actual data is hosted. To the web application in the browser, it appears that the calls are being serviced by the local web server, so there are no cross-domain security issues.

The next problem is to find a lightweight web server that can host my web app locally and can do proxy forwarding. Because it is too cumbersome to set up an Apache server, I decided to try a Windows build of Nginx instead.

The first thing to do is to set up the root from which to serve the web application’s content by modifying the root location directive in the config.

location / {
 root C:\path\to\my\project;
 index index.html index.htm;
 }

In my BSP appliation, I have a controller called process.do, which handles AJAX requests from the application and returns responses in JSON format, and which lives at the same level as the index.html file, so calls to “process.do” in the Javascript of the web application go to this controller. Therefore, I added another location directive to forward all calls to /process.do to the actual controller in the BSP application on the SAP server:

location /process.do {
 rewrite ^(.*) /sap/bc/bsp/sap/ztmppoc$uri break;
 proxy_pass http://saphost.client.test.com:8000;
 }

What this directive does is to modify the URL to point to the path of the BSP application (which is called ZTMPPOC) and forward the request to the SAP server hosted at saphost.client.test.com:8000 with proxy_pass. So a request to http://localhost/process.do?action=abc, for example, will be forwarded to http://saphost.client.test.com:8000/sap/bc/bsp/sap/ztmppoc/process.do?action=abc.

This presents a little problem though, because on the first request, SAP responds and asks for authentication, after which the URL has been rewritten, and Nginx rightly responds with a 400 not found error, because it cannot find /sap/bc/bsp/sap/ztmppoc/process.do on the local machine.

To overcome this problem, we must also pass on requests to /sap to the server, so we add another directive as follows:

location /sap {
    proxy_pass http://saphost.client.test.com:8000;
 }

This now also forwards all requests to /sap on the local machine to the SAP server without rewriting the URL.

Some background:

Firstly, I am not using SAPUI5 for this proof-of-concept. The ABAP Development Tools for Eclipse include support for SAPUI5, but this really requires you to use SAPUI5, because when it creates the BSP application, it specifies the application class as /UI5/CL_UI5_BSP_APPLICATION, which rewrites the URLs to use the SAPUI5 libraries from the server. That rules ADT out as an option for developing an application with any other third-party library, like JQuery Mobile.

It would be really great if SAP can add full support for BSP to the ABAP Development Tools for Eclipse, but for now that is just a dream.

My next attempt focused on using a WebDAV share on SAP to directly open and edit my files. This involved using NetDrive to mount the WebDAV folder as a drive. (SAP has an SICF service at /sap/bc/bsp_dev, which gives you WebDAV access to BSP applications). For the editing I used Aptana Studio, as it allows you to add a remote connection to a project, including a local directory, which is now the mounted WebDAV share. The problem here is twofold: WebDAV results in a lot of lag, so editing files is tedious, and every time you change a file that is not a MIME object but a BSP item, you need to go back into SAP and activate these entries, as they are flagged as inactive on every change via WebDAV.

That eventually prompted me to research the above solution. Now I am still using Aptana and my remote connection points to the folder where I am hosting the content through Nginx. It is a lot quicker to edit and test my code, and I am getting real data from the SAP server with which to test, which eliminates the need for stubbing responses in my code.