Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Chaim_Bendelac
Product and Topic Expert
Product and Topic Expert
4,718

TinyWorld - Part 7

Under the hood

Hello!


In Introduction to the TinyWorld application we introduced the TinyWorld muti-part tutorial, describing how to develop applications for SAP HANA and XS Advanced, using the SAP Web IDE for SAP HANA (Web IDE).

Now it is time to dive under the hood, and understand a little bit more of the concepts related to the development of multi-module applications.

As discussed in the introduction of this tutorial, business applications usually consist of multiple modules, e.g. a database model, Java or Node.js business logic, a UI app that are deployed to different target runtimes.

Development of such applications requires careful coordination of APIs and dependencies. Deploying such applications is even more challenging due to the need to orchestrate and provision the different parts and targets.

The SAP Web IDE supports the development, testing and deployment of entire multi-module applications in the context of a so-called multi-target applications (MTA) project. The development process is governed by a special meta-file, which we have already met, the MTA descriptor (mta.yaml).

The MTA project

The following illustration shows the structure of the fully expanded TinyWorld project (a few hidden "system files" are intentionally not shown):

 

The Local folder is the root folder for all projects, and represents your "workspace". There can be more than one project per workspace. A project is simply a folder structure with multiple modules. Here we can see three modules:


module type



source folder


special files


special file role

TinyDB

HANA database type: hdb

src/

-

TinyJS

Node.js (xsjs)
type: nodejs

lib/

package.json

identifies "server.js" as the "main" entry point of the application

server.js

imports "xsjs" compatibility layer and refers to "lib/index.xsjs"

TinyUI

HTML
type: html5

resources/

xs-app.json

names the default html file ("index.html"), determines whether users can access the app anonymously or need to authenticate, and declares a mapping of external URLs, called "routes"

package.json

Future: currently do not change this file.

In addition to the above structure, there may be additional, normally hidden, special files: a folder called .git/ (used by the version control system), a folder called .che/ (used to record workspace state), and within HDB source folders, two files respectively called .hdbconfig, and .hdbnamespace. You normally don’t need to be concerned with any of these files.

Each project root folder also contains the MTA descriptor, mta.yaml, discussed in more details below.


The MTA descriptor

The MTA descriptor file is automatically created and maintained by the Web IDE. When we created the application project in part 2 of this tutorial, a small skeleton was created. Initially, it didn't have a lot of interesting content:

As we started adding modules to the project, the MTA descriptor file automatically changed. Here is what it looked like at the end of part 3 of this tutorial:

Let's take a closer look.

  • Lines 1-3 are like a header, providing the application unique id and its current version. The ID and version properties uniquely represent the application version in the production environment. By convention, ID is a reverse-URL dot-notation, e.g. com.acme.demo.tinyworld. In this tutorial, we keep it simple: just tinyworld. Version follows the semantic versioning standard (http://semver.org/).

  • Lines 5-31 describe the modules of the application. Each module has a type (hdb, nodejs or ui5) and a path to its source code, relative to the MTA root. TinyWorld has three modules.

  • Lines 33-35 describe the resources on which the application depends. Here, we have only one resource, a HDI container (of type "com.sap.xs.hdi-container") named laconically hdi-container.


Dependencies

One of the most complex aspects of developing interacting application modules in XS Advanced is the question of how a module knows the access point of another module.

How can you write a UI that calls an OData service, when you don’t know what the URL of that service will be at runtime, as it can theoretically be deployed on any host under XS Advanced management? Or, how can you write a database module that must run inside an HDI container that may later be established by a HANA administrator on a productive database? Or how can you specify that a certain business logic module should only be deployed after the database module it depends on has been deployed?

The role of the MTA descriptor is to describe the logical dependencies between all the modules of an MTA. It does this with variables in "requires" and corresponding "provides" sections, and with predefined (reserved) variables, like ${default-url}. The value of this variable will be determined and substituted when the application is deployed (a topic we will discuss in more detail in part 9 of this tutorial).

Let’s examine the dependencies of our small application.

On line 10 you can see that the tinydb module uses a "requires" section to declare the specific database container to which the code will deployed (lines 10). The MTA descriptor is tracked by the development and deployment tools. For instance, when you "build" the tinydb module, the tools will automatically create and provision the necessary database container and associated XS Advanced services, technical users and permissions, both during development, and later during deployment.

Line 16 shows how the tinyjs module has a dependency on tinydb (so you won’t be able to run tinyjs unless you first build tinydb) and on the HDI container which its code accesses (line 17).

The tinyjs module has a "provides" section (lines 18-21), containing a variable tinyjs_api with a property named service_url that has the reserved value of ${default-url}. So how does this work?

Check out the definition of tinyui. As we already know, this module is going to call the OData interface exposed by tinyjs, and thus needs to know its URL. It therefore "requires" the variable tinyjs_api.

The actual "binding" to the URL of tinyjs is performed by the XS Advanced "approuter" application.

This application expects to access an environment variable called destinations, which has a predefined "grouped" structure of name-value pairs. We create this grouped structure via defining a property tinyjs_be with the value of the local variable ~{service_url} i.e. tinyjs's runtime URL. To close the loop, the same property must also be listed as a route in the approuter's configuration file, xs-app.json, as already discussed in part 3 of this tutorial:


{"source": "^/euro.xsodata/.*$", "destination": "tinyjs_be"}



To summarize: the "approuter" will use this information to route euro.xsodata to the destination URL defined by the tinyjs_be property, which is automatically mapped to the OData service of the tinyjs module.

Yes, it looks a little complicated at first, but the benefits far outweigh this. As mentioned, the MTA descriptor is tracked by the development and deployment tools which automatically create and provision the necessary dependencies and associated XS Advanced services, technical users and permissions, both during development, and later during deployment. This beats, hands-down, the need to hard-code absolute values in various "manifest" files, and modify these hard-coded values for each landscape that you deploy your application to!

Matching CDS conventions

CDS artifacts are created in a context, which adheres to certain conventions. While this is not a CDS tutorial, the following table will help you keep things consistent when creating and deploying CDS artifacts with the Web IDE:

Web IDE concept

workspace

matching CDS code

resulting HANA entity

project name P

project folder P

-

module name M

module subfolder M

-

namespace N

in file .hdbnamespace

namespace N

CDS filename C

file C.hdbcds

context C

-

entity E

table named: N::C.E in container called workspace<id>-P-hdi-container[_n]

Summary of part 7

XS Advanced is based on the cloud principles of the Cloud Foundry architecture. This imposes new challenges when it comes to developing the multiple parts of a business application, in a way that is independent of the actual system and landscape in which the application will be deployed. Here we took a look under the hood of MTAs - the muti-target source specification that makes this possible. More details can be found in the SAP HANA developer documentation.

You can continue to explore the more advanced parts of this TinyWorld tutorial, covering things like the use of version control, adding authentication and authorization control to our application, and  how to manage the life cycle of our application, from development to deployment, in the following parts of the TinyWorld tutorial:

Part 8:   Source control

Part 9:   Application life cycle

Part 10: Add authentication

Part 11: Add authorization


1 Comment