d.velop cloud customers are provided with functions in the form of so-called Apps. These provide one or more related functions for the digitization of business processes. For example, an app could only provide a single function for signing documents, or it could offer several related functions that together represent a complete applicant management system.
The following describes the requirements a d.velop cloud App must fulfill.
Technologies, frameworks and tools change. This is especially true for web development, where the framework and tool landscape changes every year. A framework which is possibly the right choice today will most likely be perceived as a burden in several years. Even if these processes of change were left out of the equation, it would probably not be possible to agree upon a uniform programming language and unifrom frameworks without the majority of the persons involved in this agreement perceiving the agreement as a foul compromise.
How would you feel if we told you that you have to use Java 5 and JSF do write d.velop cloud apps. Or what would you say if we went one step further and would require a d.velop cloud specific programming language or framework that you would have to learn and which is completely useless apart from the d.velop cloud?
We are convinced that as an app developer you can decide best which programming language, which framework and which tools you want to use and that you should be able to revise this decision as soon as a better alternative emerges.
For this reason we limit our requirements for d.velop cloud apps to an absolute minimum, with the aim to grant you as many degrees of freedom as possible, but still maintain a system, which is perceived as a single application by the end user.
We rely on established, programming language and framework neutral standards for our requirements in order to achieve a high level of stability and broad applicability.
In summary, we act according to the following principles:
- as few requirements as possible and high degrees of freedom for you as an app developer
- programming language and framework neutrality
- use of open and established standards
- as few as possible d.velop cloud specific things
Despite the desired degree of freedom for you as an app developer, there are some guidelines you need to follow, so that we can ultimately provide the end user with a safe and reliable system that feels as if he is working with a single large application and not with a large number of different and individual applications.
Actually, with HTML and HTTPS there are only 2 non-negotiable technical requirements for a d.velop cloud app. The registration of the app in the d.velop Cloudcenter is rather organizational in nature and the centralized authentication via the Identityprovider-App results from the understandable desire to only have one authentication process for the entire system.
HTML must be used for the user interfaces of d.velop cloud Apps. In accordance with our principles, we don't care which programming language or framework you use or whether you use client-side or server-side generated HTML.
Since HTML isn't exactly an exotic now, there's a good chance that you've already mastered the necessary skills. If that's not the case, then there is a wealth of free and paid for training courses available on the net. Learning HTML is certainly not a waste of time.
You already have an existing HTML application? Great! Then you have already fulfilled a large part of the requirements and you can deploy your application as a d.velop cloud app with a few simple steps. Please read the further requirements.
Each app must be accessible via a multitenant capable HTTPS endpoint that is fail-safe and scales appropriately to serve all requests of all tenants even at peak times.
The following graphic shows the corresponding system architecture.
Within the d.velop cloud each tenant gets its own subdomain under
d-velop.cloud. A tenant is
usually a company with several employees. It's paramount that the data
of different tenants is separated from each other.
All DNS entries point to the so-called Approuter. This is a part of the d.velop cloud platform and acts as a kind of reverse proxy for all apps.
Based on the 1st path segment, the Approuter decides to which endpoint the respective request must be forwarded.
Thus, requests whose path begins with
/dms/ are forwarded to the multitenant capable endpoint of the
DMS-App. Whereas requests,
whose path begins with
/home/ are forwarded to the Home-App.
How you create multitenant capable endpoints which are fail-safe and scale accordingly, is up to you. Where this endpoint runs and which domain you use is also irrelevant for us, as long as the underlying data center is ISO/IEC 27001 certified.
We ourselves use VM-based, container-based and serverless endpoints for our apps.
Since all requests for all tenants are forwarded to the same endpoint, this endpoint must be able to decide to which tenant a request belongs.
For this purpose, the Approuter adds HTTP headers with corresponding information about the tenant to each request . This information must then be evaluated by the endpoint to decide which data store the app will use to answer the request and which baseuri must be used to call the other apps of the current tenant.
- The user calls the
xyzapp of the tenant
acmein the browser.
- The DNS query for the subdomain of the tenant resolves to the Approuter.
- The Approuter adds the appropriate tenant headers to the request and forwards it to the endpoint of the
xyzapp, which is configured in the d.velop cloud center
xyzapp checks the signature of the tenant headers to make sure that the information about the tenant really comes from the Approuter. Then the tenant-id
345az3is used to identify the data store for the tenant and to answer the request accordingly.
The tenant-id is a unique and lifelong valid ID for a tenant that is not assigned anew. This ID is therefore suitable to permanently identify a tenant and to separate the tenant's data from the data of other tenants. How this separation is implemented depends on the database management system used. For relational databases, the use of separate schemas is an obvious solution, while using the tenant-id as a part of the key (e.g. as a prefix) is an appropriate solution for key value stores.
Not only the communication from the client (browser) to the apps, but also the communication between the apps goes through the Approuter. Therefore - besides the name of the target app - an app that wants to call another app must know the baseuri of the tenant for which a request should be made. This is transmitted in the x-dv-baseuri header.
Since the apps communicate with each other via the Approuter, the tenant headers do not have to be set by the app when calling other apps. The Approuter does this automatically.
To ensure that the client information actually comes from the Approuter, it is mandatory, that each app checks the HMAC-SHA256 signature transmitted in the x-dv-sig-1 header. The app calculates the signature according to the following procedure:
Signature = HMAC-SHA256 ("<value of x-dv-baseuri><value of x-dv-tenant-id>",App Secret)
and compares the result to the value of the x-dv-sig-1 header. Note that the value in the x-dv-sig-1 header is base64 encoded.
The above mentioned App Secret is an exclusive secret between the Approuter and the respective App, which is assigned as part of the registration process in the d.velop Cloudcenter. As appropriate for real secrets, you must not shared it with other parties. Should this happen accidentally, a new App Secret for the respective App can be created in the d.velop Cloudcenter.
If the comparison fails, i.e. the calculated value for the signature does not match the one in the header
then the app must reject the request. Usually, the HTTP status code
403 Forbidden is used for this.
The following example can be used to validate an implementation:
x-dv-tenant-id: a12be5 x-dv-baseuri: https://header.example.com App Secret (base64 encoded): ptuQ0b0BskmLLxXsjjhH9Su8ozTvZl6Z/5/HlaORoRg= x-dv-sig-1 (base64 encoded): Zjcf28p5aQ6amtbs6s9b9cPyBPdziwUslR2DZqaGUTQ=
The Identityprovider-App serves as the central point for authentication in the d.velop cloud, i.e. for the question "which user is sitting in front of the device".
In addition to its own identity pool, the identity provider supports a number of external identity providers such as Google, Azure AD or Facebook, so that users of the d.velop cloud can also log in with their existing credentials, if they already have an account at the aforementioned services and the respective external Identityprovider has been activated by the administrator of the particular tenant.
After a successful logon, the Identityprovider-App creates a session for the logged-on user that can be used by all other apps in the d.velop cloud to uniquely identify the user.
The Authorization, i.e. the question "What the logged in user is allowed to do", can only be answered by the respective App since the authorization process requires domain knowledge.
The following image shows the authentification process:
- The user invokes an arbitrary d.velop cloud App. In this example the Hello-App in the tenant acme
- The Approuter adds the tenant headers (not shown here) and forwards the request to the Hello-App.
This app realizes that the request does not contain any authentication information and therefore forwards the client to the
loginresource of the identity provider via redirect (HTTP status 302 Found). The originally called resource
/hello/worldis passed as an URL-encoded query parameter.
- The browser automatically follows the redirect, so that the request ends up at the Identityprovider via the Approuter.
- The Identityprovder does not find any authentication information in the request either and therefore authenticates
the user against the internal identity pool or against the configured external identity pool (not shown here).
If the user has been authenticated successfully, the Identityprovider sets an
AuthSessionIdcookie which identifies the logged-on user and then redirects the client to the originally called resource
- The browser automatically follows the redirect, so that the Hello-App again receives a corresponding request. However, this time the request contains a authentication session.
Hello-Appp receives the request with the authentication session (AuthSessionId), but doesn't know user belonging to this session. To determine this, the Hello-App calls the
validateresource of the Identityprovider and send the authentication session as a Bearer token. Note that the bearer token is not URL-encoded.
- The Identityprovider already knows the user belonging to the authentication session and answers the request with a standardized JSON object that contains information about the user. Among other things this SCIM User Object also contains a stable ID for the user, which is valid beyond the validity of the authentication session. Note that the authentication session expires after a time specified by the Identityprovider and therefore is not suitable to identify the user permanently.
- Now the Hello-App has all the information it needs about the logged-in user to authorize and
answer the request. The respective App should store the SCIM User Object for a given AuthSessionId to avoid
running through this whole process again and again for every request. The
Cache-Controlheader set by the Identityprovider provides the information about how long this information may be cached.
At first glance the process shown might seem quite complicated. However, a large part of this process is executed by the browser or the Identityprovider under the hood. For the remaining part, which has to be implemented by all d.velop cloud apps, we provide Open Source SDKs on Github.
A description of the Identityprovider-App API is available in the Developer Portal.
If you decide to use a different authentication mechanism the user must log on several times during the course of his or her workflow. He must also have user accounts with multiple identity providers in order to use the entire system.
Apart from the HTML frontend, the multitenant HTTPS endpoint and the Identitprovider Integration there are in fact no further mandatory requirements. However, there are some additional things we strongly recommend. At least you should know the consequences if you disregard these things.
Our strategy is to develop our HTML UIs only once and to use the same UI on different devices such as desktop PCs, tablets and mobile phones. For this reason we use Responsive Webdesign. for our HTML UIs.
Futhermore we use Material Design from Google. As a design system this includes not only a collection of components for web development, but also extensive guidelines and principles that describe in which situation which UI element should be used and how.
Since all of our UIs use material design (or are currently being migrated to it), the user gets a uniform look & feel and the boundaries between the UIs of different apps are not visible anymore.
Despite the design system, as a developer, you are usually not necessarily able to create visual attractive UIs in a short time. For this reason, our design and usability team provides several Open Source Templates for whole HTML pages, which are a good starting point for your own interfaces.
If you decide to develop UIs which are not responsive, you will lose the customers, who want to use your app on mobile devices or various integrations. If you are using a component collection or design system other than Material Design, then the transition from one of our apps to your app becomes visible to the user, which might reduce the usability and your app might not get the approval it deserves. However, especially when integrating existing web applications, it may make sense to first integrate your application in the d.velop cloud and then switch to responsive UIs with material design. However, since this process generates effort, you should use responsive web design right from the start for new apps.
Right now we support the following browsers on the given operating systems or devices for the d.velop cloud:
- Internet Explorer 11 (support ends October 2021), (Chromium) Edge, Chrome and Firefox on Microsoft Windows
- Chrome on Android starting from Android Version 5.0
- Safari on iOS (iPhone/iPad)
- Safari on MacOS
For Edge (Chromium based), Chrome, Firefox and Safari we only support the latest version.
As an App Builder, you should the same browsers so that your app runs on the same devices and browsers like the other apps in the d.velop cloud. Otherwise you will not reach some customer groups.
If you have already used the d.velop cloud or d.3 one on-premises, then you certainly have noticed, that we use a certain UI Layout with two HTML pages displayed simultaneously most of the time. There is also a kind of menu and you have the possibility to change the display to fullscreen mode and so on. Furthermore some context switches from one HTML page to a new page are animated from right to left.
These and other functions are provided by the so called Shell-App, which uses separate iframes to load the HTML pages of the different Apps. The Shell-App provides the means to proper isolate the pages of the different Apps so that every developer can use the HTML framework of his choice and at the same time a homogeneous user experience is achieved.
The Shell-App Integration is not very time consuming and is also unobstrusive. One of the main goals during the conception of the Shell-App has been to provide the means to integrate existing HTML pages with minimal changes to the page. The API description explains how to integrate your web application into the Shell-App.
If you already have an existing web application you probably can start without the proper integration into the Shell-App. But very quickly the user will wonder why new websites don't appear in new iframes and instead the existing content of a single iframe is updated on every context switch. Furthermore the Shell-App controls would not available if your web application would be called directly using a bookmark or a link. To make a long story short, you should integrate your web application into the Shell-App right from the start to achieve a good user experience.
As soon as a tenant has booked your app in the d.velop cloud, the users need to know, how the different functions of your app can be used. One possibility would be, to inform all users about the URIs for the different features of your app, so that they can find bookmark them.
Of course this is not very user-friendly, so we decided to use the Home-App for this purpose. This App provides - analogous to the Home screen on mobile devices - the function of a central entry point to all features of the booked apps.
The API description of the Home-App provides detailed information how to register the features of your App.
Of course your App can be used without registering the features at the Home-App but it might be a little difficult for the users to find your features if you don't do this.
In addition, there are some more recommendations which are listed below. Whether you want to follow these is up to you. We follow these recommendations and benefit from the resulting loose coupling of our apps, so that we don't want to withhold these recommendations from you. Even if you don't want to follow these recommendations - which is perfectly all right for us - the knowledge of them might be helpful to understand the usage of our APIs.
For some years now we have been confronted with the challenge of working on a conceptually single piece of software with a steadily increasing number of developers. So we worked on a solution which allows us to build independent teams which work on separate parts of the system and to assemble these parts later on in such a way that the appear like a single piece of software from the customer's point of view.
The classic separation into frontend, backend and, if necessary, data storage reaches its limits here, as this allows a maximum of three teams. Not to mention that these teams are anything but independent. On the contrary! Even to provide the smallest additional functions usually all three teams have to work together and to agree upon appropriate interfaces.
Instead of forming the teams according to horizontal, technical layers, we use vertical, business oriented slices, to divide the application domain into several building blocks. The challenge is to identify building blocks which have as little as possible dependencies to the rest of the domain. If you manage to find such blocks then these blocks can be developed by really independent teams. Internally, these blocks contain the usual layers (frontend, backend, data storage). However, the interfaces between these layers are now an internal detail of the block and invisible to other blocks.
These blocks are our Apps. We prefer links in the frontend to assemble these blocks to a virtually single application for the user. This allows us a much more looser coupling than an interaction at data level.
For example, suppose that the Task-App contains tasks that refer to documents in the DMS-App. "Please review the document". In this case it makes sense that the user sees the document while working on the task.
One way to solve this problem would be to provide an API for the DMS-App which could be used by the Task-App to retrieve the document data. Then the Task-App could use the document data to render a presentation of the document in its own UI fpr the task.
But what happens if the API of the DMS-App changes?
For example, the name of a JSON properties could change.
In this case, depending on the implementation, an error would occur in the Task-App, or at least
information about the document is missing as long as the Task-App has not been adapted accordingly.
Now one could argue, that such changes of the DMS-App API should be prohibited.
But the broader an API is, the higher the danger that one
comes into a situation where a change of the existing API cannot be avoided.
Even if it is possible to keep the API of the DMS-App stable, the question arises what happens if the
DMS-App enhances its own visual representation of documents. Even then, the Task-App would have to be adapted first in order
Therefore, in this situation it is much more elegant to link from the task of the Task-App to the corresponding document in the DMS-App in the UI.
The API is much smaller. Ultimately, only the URL to the linked document must remain stable, so that the risk of an incompatible change is much lower. In addition, the Task-App benefits immediately and without further adjustments from future improvements of the UI for documents.
Both the team of the Task-App and the team of the DMS-App benefit from this type of (de)coupling.
We did not invent this architecture and we are not the only ones who architect their systems in this way. Meanwhile the term Self-Contained Systems (SCS) has been coined to describe such architectures.
Sometimes the business case to implement does not allow linking in the frontend. For example, with the server-side archiving of emails no user and therefore no frontend is present.
To support such cases we provide RESTful HTTP APIs with JSON representations. In particular, we use the JSON Hypertext Application Lanuage in many places, to express links between different resources in JSON format.
If your own use case falls into this problem category, in which a link in the frontend makes no sense, then there is most likely already a suitable JSON API for it. If this is missing, then you have a good chance that we will extend the API accordingly. If, however, you goal is to create an alternative UI for an already existing HTML user interface then you won't find - at least at this point in time - the appropriate API functions to reach your goal. But please contact us, so that we can understand your goal an work together to find a solution.