App Development on SAP BTP: Taking Digital Transformation by a storm
- Using Fiori Design concept
- Consuming APIs built on top of Cloud Platform Integration
- Using OOTB Security features
- Integrating with corporate Github for Version Control, and
- Touching on the activities related to the Deployment process of the final product.
At the same time I’ll share some amazing resources I came across while building this application. There are few learnings that I have mentioned throughout the length of this blog post which I couldn’t find so easily over the web but finally was able to figure out with the help of few of my colleagues here in SAP. Stop! Wait a minute:
What’s with all the buzz about BTP?
To start with, it seems like a one stop shop for building a quality business application. But…. I can develop one from ground up using traditional ways of development. Well that’s where the difference lies. When I started building this application, I was not much aware of how:
- The Design is actually going to meet a standard: My UI Design skills, ever since Uni, certainly haven’t been the best.
- I would be polishing up my application: Of course designing the application is one thing, but what about security. Honestly, I hadn’t ever built a production ready web application where I had added User Authentication on my own. It just seemed like a boilerplate task and mostly ended up in someone else’s plate (No can do).
- I would be deploying the application: Deployment – DevOps. I had always been a backend developer for crying out loud. I am not going to meddle with how the ‘other team’ is going to deploy the application.
Well, now just read the above bullet heading but without my litany of excuses. I was able to do all of that. Did I fret a lot with doing that? A bit (let’s be reasonable), because it takes a bit to adapt to a new platform, but it certainly took far less amount of time had I taken the traditional approach.
Hello World SAP Business Application Studio
Business Application Studio is your new playground where you do everything development. Sleek IDE on the cloud, has most of the features that you would expect from a bull blown IDE. Can we ask for more? Absolutely, yes! But let’s give it some time, the product team and developers at SAP have their thinking caps on and working to provide best possible features with each incremental release. With plethora of pre-defined templates available, based on the project, choose one template and fast forward to what’s required. I was building a SAPUI5 Application, I chose a Fiori Freestyle Application template. There is already a lot of collateral available over the web on how to get started with creating such an application, you can follow the steps stipulated in this tutorial. Something worth noting here though, SAP used to have an IDE on Cloud, previous to Business Application Studio. It was called SAP Web IDE. So in case anyone comes across the term (which you certainly would even within the platform), just remember it as SAP Business Application Studio’s predecessor.
The two important things:
Views (in this blog post are only mine but also SAPUI5’s)
Don’t get taken away by the heading. View as the name suggests is the actual way in which your UI screens are going to look like and eventually depend on. While traditionally we depend on writing HTML to develop the skeleton of the UI, we do the same thing using the Views. Each screen in your application is going to be controlled by what you define in these views. You have the ability to type in code so as to define elements in these views: a button, text area, nav bar, what not. But, the good part is, the IDE provides you another ability to define these elements in the view via just a drag and drop of elements. So if you are new to the SAPUI5 syntax, the Layout Editor has got you covered just right.
Things that put a smile on my face:
This is where the java script code that ultimately controls most of the actions of the elements in your views, reside. Nothing fancy here, just the regular JS.
Consuming External Services
Certainly a topic which took some time for me wrap my head around. If you’ve built web applications, you might already be accustomed with maybe putting in those ajax calls to make API calls to external services in order to integrate with backend applications. Now, you can do the same things here too. But it doesn’t necessarily stops here. You can go for glory by using something called Destination service, that’s another offering that BTP provides so that you can integrate with other solutions like SAP Business Application Studio.
It is the
journey Destination that matters
The Destination service can be thought of as a microservice. If you want to connect anything BTP with the external world, which could be a service running on Internet, another SAP System or for that matter a service running on your local machine or an on-premise system – Destination service is a one stop solution for any of those things.
Example: I was supposed to make REST calls to an iFlow deployed in Cloud Foundry. We had defined a Base URL to the service in the Destination Service in the BTP Subaccount. What this meant was that:
- I no longer needed to hardcode the Service Base URL in the codebase.
- What it also meant was, I no longer had to define any of the authentication credentials in the code either.
- I only needed to tell my code that “when I’m calling a particular relative path, just call it using a specific Base URL which has been defined in this particular Destination”. Viola, that was a game changer.
- Another benefit I realized going this route was that I did not get those CORS errors.
- And at the end, Destination Service serves as a re-usable component which can be used readily by any other developer alike for their specific needs.
More on configuring the Destination and using them, this is a really good blog post.
Certain challenges I would like to point out here, per-se the struggles:
- Using the Destination defined at Subaccount Level and making it work while testing your application Locally in Business Application Studio
- At first it wasn’t that apparent. But you can do it very easily.
- All you need to do is, in the Run Configuration of the application, bind to the Destination that you have defined in the Destination Service.
- This can be done by clicking on the plug icon right next to the Data Source and selecting the appropriate Destination. In my case, the name of my Destination was CPI_BaseURL.
- An Important step after this is essentially the one that left me scratching my head for a bit. When you Bind the Destination to the application this way, by default this functionality sets the path as ‘/sap‘ for this Destination. This means that whenever in the code there is a relative path starting with ‘/sap‘ only those API calls will be routed to the selected Destination.
- So make sure that in the file .vscode/launch.json, you correct the path to match it to the start of the relative path that you have actually coded in the code base. Eg: the relative path in may case was ‘/transform/cxml‘. In the launch.json, you need to specify ‘/transform‘ instead of the default ‘/sap‘ so that this new relative path gets bound the Destination.
- The other hiccup was, invoking this destination when the application was deployed on Cloud Foundry. The problem lied in very intricate details while defining the routing and also while defining the relative path in the code.
- For the Destination to work on the application running locally on Business Application Studio, the steps defined above are the only ones required.
- This definitely doesn’t hold true for the application deployed on CF.
- As you might have already gotten an idea from the blog post shared above, you need to define the destination in mta.yaml. Once defined there, you need to use this destination and define a routing to this destination in a file called xs-app.json.
- So essentially what you did in the previous activity for the destination to run locally in Business Application Studio, you need to perform the additional two things mentioned in the last point for the destination to work on CF.
- That doesn’t necessarily end there. Make sure of the routing and how you define it.
- To start with, I had a routing define like the one below:
Let’s talk about what some of these attributes mean.
source: any relative url path defined in the code that resembles this regex, that is going to route to this Destination.
target: while routing to the destination, the relative path that is going to be used or appended to the Base URL is going to be defined hereUsing these two concepts, let’s take the example of the Relative URL that I had used in the ajax call, and how it would get routed.Relative URL: transform/cxml
The source regex is going to identify it as a correct candidate for using this Destination.
The target defined “$1” is going to make the relative path as just /cxml though, instead of /tranform/cxml. Why did this happen? “$1” notation says that anything defined in the wildcard “(.*)” in source is the only part that needs to be considered while forming the relative path.In such a case, you might get a http_status 404 while invoking the Destination from code since actually there is no such service with such a relative path defined in the server side.So to correct this misunderstanding, we need to clearly define the target so that it can consider the prefix /transform as well. So the corrected routing looks like below:
- Also a word of caution while defining the Relative path in the code. Do not prefix ‘/’ before the relative path when it is defined in the http call for example in the ajax url. The ‘/’ would essentially signify to the router that- use the base URL of the deployed application rather than getting routed to the Destination via the mapping. In such cases you might get a http_status 403 while invoking the API call from the deployed application
- The browser devtools always show the Base URL of such calls as the URL where the initiator web application is deployed. So you cannot see the actual server endpoint that is being called, since the request routing is happening internally via the Destination service. So this essentially aggravated the debugging process as to why my initial routing wasn’t working and reason was not so apparent in the start. In case some one has an idea on how we can actually see the internal routing or actual calls to the external service, maybe via some other tool that BTP offers, please let us know in the comments.
From very little of what I have seen so far, if you are configuring OData services in the application, the setup will not include these kind of issues or hardships defined in the first two points. The setup of OData services is part of the template configuration, so the pre-defined steps take care of all such intricacies. In SAP’s landscape, there is more dominance of OData services than REST (literally too 😉 ). So as of now with REST endpoints, the setup is still a bit manual and quirky.
I briefly touched a bit on this topic while talking about Destination in the earlier headings wherein I explained how by using the Destination Service I can basically omit putting any security credentials in the code base while making calls to External Services.
Another cool feature which these Application come with is something called XSUAA (eXtended Services for UAA). I cannot do justice to this topic so I would actually defer to another blog post written by our SAP Colleagues who have done a brilliant job at defining all about XSUAA. As for a highlight, this feature adds authentication on top of your deployed application such that only people who have been granted the role to access it can view and use the application. A small example being, I needed to grant access to this application to only the relevant stakeholders. Only they will be able to access the application while others will get an Authentication error when they try to do so. Again, it doesn’t require any manual work to setup so it fast forwards the development around security aspect as well.
While building applications that cater to your business, it might not be recommended to do away with such an authentication, BUT if you want to open your application to the outside world or for whatever reason, you can merely disable the authentication by defining “authenticationMethod” as “none” in xs-app.json
git commit -m “Integrating with Corporate Github”
If you are maintaining or planning to maintain the Application code base in your corporate Github, in all honesty the setup is not going to be very straightforward. I came across this blog post here that clearly defined all the steps I needed to take in order to start using corporate github. Shoutout to the blog post!
As defined in the blog post I shared above, you will need SAP Cloud Connector since it plays a major role for this setup. If you are using an Enterprise BTP Account (like I was), chances are that you might be provided with a Custom Region at the sub account level, which might not be listed in the default Region list present in the Cloud Connector. In such a case you will need to create a Custom Region in the Cloud Connector in order to go ahead with the setup. You can refer to the documentation here which talks about the steps to be taken into consideration for setting up Custom Region in Cloud Connector. The Region name defined in the Subaccount hinted a bit on why a custom region might be required, but what led to me ascertain this was a number of failed attempts while connecting SCC to the subaccount and finally checking the API Endpoint defined in Cloud Foundry Environment. This fact was not very clear to me as this was the first time I was using either of these Solutions, so I really wanted to bring this up here.
Previous to setting up the Custom Region, I was trying my luck with the Europe (Frankfurt) AWS Region in SCC Subaccount setup. In the logs I could see the connection failing due to 403 Forbidden. So just a heads up in case anyone runs into the same. The SCC logs are pretty useful so that should be the first place for debugging the issues.
Deploy, Ahoy !!
The Deployment of the HTML5 application was actually a very straightforward experience, until the it wasn’t. I was working on a new Subaccount where most of the setup was basic, certain entitlements were missing, some roles weren’t assigned so we had to provision all these on the go as the need arose. But in its all entirety that was a pleasant experience because this way I got to understand how certain things actually worked.
I had been following the steps mentioned here for building an deploying the MTA. Once the build process successfully completed, I started with the Deployment process. Now here came trouble.
- When I entered in the CF URL, entered my Subaccount credentials, the Deployment terminated with an error stating ‘There are no available organizations’. What I understood from this was the fact that my Subaccount User was not a member of the Cloud Foundry Organization within the Subaccount. Additionally at that moment, we did not have any Space created within CF for deploying the application.
- So all it took was adding my user to the CF Org Member list and creating a Space for deploying the Application. Also, in order to be successfully able to deploy the application to the Space, you also need to be assigned with the Space Developer role. If you are not part of it, you will see an error around it as well during the deployment process. Documentation which I specifically found helpful was the official Cloud Foundry Doc which talks about all these concepts.
- If yours is a HTML5 application, you will see the deployed application under the HTML5 Application within the Subaccount. If you do not see it there, then probably you are missing an Entitlement either to SAP Launchpad or SAP Cloud Portal. Once you start seeing the application there, you can click on it and it will redirect you to your web application.
- Within the Cloud Foundry Space, you will observer that there are multiple instances running. Some of them would be of the Destinations that you have been using within the application, other services like Launchpad etc. But you might not see your HTML5 Application there. Well, from what I have read is that this is the expected setup if you are using a SAP Managed App Router in your web application, so don’t be taken away by that observation. More on SAP Managed App Router vs Standalone App Router can be read here.
This application was a pretty good way for me to get my hands dirty with and explore the possibilities with BTP. Of course the topics that I have touched in this blog post are limited but they are something that I found interesting and worth sharing my outlook about. Certainly the adventure doesn’t stop here. I have only explored bits and pieces that seemed relevant with the scope of the application. There is a lot to watch out for in the huge portfolio of BTP. I’m sure there will be many new developments on each of the fronts and I’m honestly looking forward to exploring more in this platform.
Well, if you’ve reached here, kudos to you for having gone through the entire post and reaching the finish line 🥇. I’ll be happy to hear about your feedback or questions about this post, in the comments below!
Have question on a specific topic? Skim through or post relevant questions by visiting this link. The amazing community will certainly be there to help you out!
thank you for summarizing the building blocks of BTP...
Thanks Rafi! Glad this was helpful.