XS Advanced for (not so) dummies: Routing
Remember how in the first post of these series, we called Web IDE but we were redirected to the UAA screen asking for our user name and password? We will understand what happened there after we understand the concept of routing in XS Advanced.
But first, coffee architecture
As developers, we also need to understand what is going on behind the IDE to make better design decisions. Your system administrator or BASIS friend will also appreciate that (and it’s always a good idea to have them on your side).
You can find the following picture as Figure 4 in the SAP HANA Administration Guide.
All those coffee drinkers (devs, deployers, admins) and users will use a URL to access an application. In the example of the first blog, we called the Web IDE using the default hostname and port in a HANA express system (https://hxehost:53075 ). That’s a request.
Take the word Web dispatcher… savor it…it’s almost self-explanatory.
Well, maybe it isn’t: it catches the requests from a client used by the coffee drinkers (a browser, the Command Line Interface, etc) and sends it to the right application.
Before it can send it to the right application, the controller needs to know the following:
- Which applications are running:It knows because it keeps the applications and their state in the BlobStore and ConfigStore.
- The entry endpoint of that application: It knows which is the right app thanks to either the port or some magic redirection using the subdomain (a.k.a, hostname based routing). An MTA has it’s own entry point. We’ll see this later.
- Whether the user is authorized or not to access that resource: That is, whether the request comes with a token id saying it’s ok to show content to that user or the user needs to provide credentials to get such pass.
A sample conversation between the coffee-drinking user, the Web Dispatcher, the UAA service and a Super Cool App would be something like:
(Yes, I know sequence diagrams… but wasn’t this more fun?)
Now yes, understanding routing in XSA development
Let’s say your application is the Super Cool App. You’ve built it using the introductory tutorials for XS Advanced and right after you cloned the initialized repo from GitHub, you created an HTML5 module. This web module has an index.html file that should be presented to authenticated users first.
Read that functional spec again: “authenticated users”. Do we build a little table with users, passwords and scopes they can access for each micro-service? Not ever since the first tiny app at school and luckily never again…
Go back to the architecture diagram above and take a look at the UAA box. It has everything you need, right?
You need an instance of the UAA service for your application, so you create it with xs cs xsuaa <<plan>> <<service instance name of your choice>>.
So how does the app know you have a UAA service it can use?
- You added the new service to the mta.yaml file, as a resource
- You want it to be deployed first, because the web module will need it, so you also add it as dependency for your new web module
- You are modifying the authentication method in xs-app.json to route.
Is that it? Now the web module magically uses routing?
This looks like magic but it is not. Something is reading that xs-app.json file. Go and open the package.json file that Web IDE kindly created for you:
There’s the anonymous hero here: the approuter.js module. This Node.js module was automatically included in the file that lists the basic dependencies for your web module to run.
Even if you do not know what package.json is for, I bet you can appreciate the scripts section. The first thing that seems to get started is the “approuter.js”. Just like the web dispatcher to the platform, this app router serves as an entry point for an MTA application. It is the entry endpoint the Web Dispatcher talks to and the one responding that a user needs authentication or delivering the index.html (welcomeFile).
The router will look for the xs-app.json file in its working directory and there is when it bumps into the “route” value (it could also have a “none” value). This simply means the definition of how to authenticate is delegated in each route configuration:
And you can see all of the authentication types are “xsuaa” because our applications shouts “you shall not pass”. It could also have “basic” or “none” as values but you want it to call the UAA Service you instantiated using the CLI.
How does it know that is the Service you want?
Because, remember, you declared it in the resources section in the yaml file and it got bound to your application when you built (deployed) the modules (or using command xs bs):
These binding process sets a super environment variable called VCAP_SERVICES that stores the services bound to an app and their config so it can invoke them later. Here is a sample output for command “xs env <<app>> ” showing the VCAP_SERVICES variable:
And you may (or should) be wondering who is “core-backend” in the routes destination? That’s another variable you can set on the the yaml file for example. It could have whatever value you want as it is an identifier for the node.js module declared as a destination:
If you are still struggling to understand the MTA.yaml file, I would encourage you to read the help. They have already explained it better than I ever could.
A reference for package.json is also provided here.
It was this CodeTalk video with a very quick intro to XSA and Web IDE that inspired (reminded) me to finish these series. i think we can wrap it up now. Not because I have covered all the topics but because you can continue on the path to XSA ninja on your own.
If you think this can be of use for someone else, please share.
As usual, i would love to stay in touch on Twitter or on LinkedIn and see what you are building. Cheers!
PS: For those of you asking for some specific tutorials on XSA (Fiori Launchpad, API calls, OData V4 and Java, three-dimensional localization of a cat), I do hear you and keep your wishlist. Time is the only constraint.
This is great work. Thank you!
Hi,
I am primarily from a SAP Basis background, and read through all the blogs in this series.
Real eye opener. Thanks for the same.
One thing that is not clear to me is - when we talk about the Hana Database service in this blog and also the earlier ones, are you referring to an Installation of Hana DB or to consume as a service from SCP(SAP Cloud platform).
I did refer the help.sap.com pages for Hana XSA which can be installed as a Stand-alone or cluster installation as part of Hana DB but was wondering if that supports the Micro services that are described in this series or should we only leverage DB service from SCP.
Hi, Mahadevan,
Thanks for the comment! I'm glad it helped.
The short answer is that all of this is on-premise. I'm mentioning a lot of services up there but I am guessing you are referring to the HDI containers / HANA managed services?
The longer answer is that XSA is the on-premise, HANA-ready version of Cloud Foundry. So, yes, the micro-services and many of the managed services available in Cloud Foundry are also available with XSA and vice-versa. As a matter of fact, an app created in an on-premise HANA instance with XSA can be deployed into Cloud Foundry.
You can check this out yourself with the full image of HANA Express, using the options on the right here: https://www.sap.com/developer/topics/sap-hana-express.html#flowchart
Cheers,
Lucia.
Take my bow ?
Hi Lucia,
Thanks for sharing the information.
I am facing the same issue where I need to read the destination configuration in the XSJS file, so my question is can we maintain/initialize the global variable VCAP_SERVICES without using the CLI, if yes then How?
Thanks in advance!
Hi Naman,
I’m not sure I understand what you are trying to do.
To create a destinations in VCAP_SERVICES you can use the mta.yaml file as in the example in the screenshot above (that is coming from here: https://developers.sap.com/tutorials/xsa-xsjs-xsodata.html ).
To set environment variables with the CLI, the command is xs set-env .
Cheers,
Lucia.
Hi Lucia,
This may not be relevant to this post, but I think it's close 🙂
We have performed a HANA rename to change the domain that the server is assigned to, for example server.abc.com to server.xyz.com. Everything looks good, however when attempting to get to any of the XSA apps like WebIDE, XSA-Admin, etc, when clicking the link, it redirects to the old domain. Are there any steps that need to be performed that are specific to XSA after a HANA rename?
Thanks!
Jayson
Hi Jayson,
There are some steps specific to renaming the XSA domain name. I have an explanation tailored to HANA Express here: https://blogs.sap.com/2018/06/20/hana-express-and-xs-advanced-when-you-cannot-modify-the-hosts-file.../
I would recommend checking the administration guide if you're not using HXE.
Best,
Lucia.
Thanks Lucia!
Hi Lucia Subatin,
thank you for your great blog.
I’m still wondering about the part: And you may (or should) be wondering who is “core-backend” in the routes destination?
Can you explain or maybe show where “core-backend” appears all over the place.
I also get an error, when I try to run my html5 module in webide and with run configurations "on cloud foundry". I do not have any java module, I don't know where it comes from. Maybe I can't request the module because of this.
Best regards,
Paige
Hi Paige,
Please note the screenshots here are based on premise XS Advanced. You don't create a destination in this environment as you can do in SAP Cloud Platform Cloud Foundry.
Destinations are processed by the approuter. In this example, core-backend is the name of the destination, not an application. The destination is then used to define different routes (i.e., what processes the different incoming requests).
As you an see above, in the mta.yaml file, I'm setting the value for destinations into the environment variables in the definition of web module. The web module contains the approuter module.
In xs-app.json, you can see the same destination (the name needs to match) and what the URL would look like for a route using that destination.
As for your application, I cannot possibly guess what is wrong without more context but this may be helpful in the Cloud Foundry context: https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/3cc788ebc00e40a091505c6b3fa485e7.html . You can also mimic the destinations as created by the "SAP Cloud Platform Business Application" wizard with "use HTML5 repository" flag on for the web module, and get a similar structure to the one described in this post. For support on your app, I would suggest you add the details of what you are doing and when that error happens in the Q&A.
Best,
Lucia.
Hi Lucia Subatin,
I have mta project in SAP HANA 2.0 and web module in this project.
And i have odata service in our corporate networt( XSODATA service).
A want to redirect odata request from web module to our public odata service, but if i write full url in manifest.json the CORS error is arise.
And when i try to use xs-app.json it doesn't work too. Redirection to the destination doesn't work.
Maybe i can write direct url to our public odata in this file? Or some other ?