2019

Nov
04

Time to go NERD - Wie mit NodeJS und Domino API fokussierte Applikationen entwickelt werden können


In diesem Blogpost möchte ich erläutern, welche Vorteile Node.js Domino-Entwicklern bietet und wie eine Full-Stack Applikation mit Node.js und Domino aufgebaut ist.

Die Laufzeitumgebung (‚N‘ - Node)

Mit Node.js und dem von HCL entwickeltem Domino-DB Modul ist es möglich, beliebigen Applikationen Domino-Daten bereitzustellen. Damit diese Daten einer Applikation zur Verfügung stehen, sollte mithilfe des Domino-DB Moduls und einer Middleware (z.B. Express) ein Microservice bzw. eine API entwickelt werden. Über diesen API-Endpunkt kann die Applikation dann Domino-Daten senden und empfangen. Dank der Entwicklung von Applikationen auf Basis von Microservices können beliebig viele Applikationen auf dieselbe API und damit dieselben bereitgestellten Daten zugreifen.

HCL verfolgt dabei die Strategie, dass Node.js als parallele Entwicklungsplattform neben den standardtisierten Domino-Entwicklungswerkzeugen eingeführt wird. Dies ermöglicht vor allem Webentwicklern, bestehende Domino Applikationen und Datenbanken durch neue Darstellungs-und Inetraktionsmöglichkeiten für eine Vielzahl von Endgeräten und Services attraktiv zu machen.
Wie auch in der "klassischen" Node.js Entwicklung nutzt der Entwickler verschiedene Frameworks, welche die unterschiedlichen Bereiche einer Applikation abdecken. Es wird dabei vom sogenannten "Stack" gesprochen.

Ein von HCL hervorgehobener Stack ist der NERD Stack. Dieser vereint die Laufzeitumgebung Node.js mit den Frameworks Express React und Domino. Grundsätzlich kann jedoch jedes Javascript-Framework in Verbindung mit Node.js und Domino genutzt werden.
Der große Vorteil eines Entwicklungs-Stacks besteht darin, dass die UI-Ebene unabhängig von Middleware, Server und Datenbankebene ist und durch beliebige UIs ersetzt werden kann, ohne die Architektur zu beeinflussen.

In unserem Beispiel wollen wir eine Web-Applikation für mobile Endgeräte realisieren. Dafür sind unter Umständen andere Gestaltungs- und Kontrollelemente notwendig.

Das Frontend (‚R‘ - React)

Wie genau funktioniert denn nun eine Javascript UI Framework mit Node?
Zunächst sollte klargestellt werden, dass diese UI Frameworks (Angular, React, Vue, etc.) kein Bestandteil von Node.js sind und ohne eine Node.js Instanz auf einem Webserver lauffähig sind.
Wenn wir nun also ein solches UI-Framework mit Node.js nutzen, so dient es uns in der Essenz als Webserver, welcher uns Webseiten anbietet und unseren Frameworkcode ausführt.

Diese Framework-UIs können auch als Webforms per Domino implementiert werden, doch es gibt zwei große Vorteile in der Verwendung von Node.js:
  1. Ist der gesamte Stack in JavaScript programmiert, ist eine Kommunikation zwischen den Ebenen der Applikation einfach, da alle Daten im JSON Format vorliegen.
  2. Bereits etablierte Stacks und Third-Party-Frameworks mit einer großen Entwicklergemeinde im Hintergrund, können genutzt werden und erweitern somit den Handlungsspielraum in der Lösungsentwicklung.

UI-Frameworks gibt es für jegliche Präferenzen und Anwendungsfälle, trotzdem ist das Funktionsprinzip bei allen identisch. Man bettet Code in seine HTML-Webseite ein und ruft damit eine Frameworkbibliothek auf, um dieses Framework auf seinen Seiten zu verwenden. Das Besondere dabei ist, dass all diese Aufrufe in den Dateien geschehen, welche vom Web Server bereitgestellt werden. So muss der Server (Domino, Apache, etc.) die Daten lediglich anbieten, wenn der Browser diese anfordert.
Folgender Code beschreibt einen sehr einfachen Anwendungsfall, in dem eine Middleware (hier Express) eine index.html in einer statischen Dateistruktur an den Browser zurückliefert.


1
2
3
4
5
6
7
8
const express = require('express');
const app = express();
app.use(express.static(__dirname + '/public'));
const hostname = '127.0.0.1';
const port = 3000;
app.listen(port, hostname, () => {
console.log(`Server running at https://${hostname}:${port}/`);
});

Folgende Struktur wird so oder so ähnlich in dem meisten UI-Applikationen zu finden sein:


1
2
3
4
5
6
7
8
9
10
11
12
node
| server.js
| package.json
|
+---node-modules
| \---(node stuff...)
|
+---public
| index.html
| other framework files...
| +---framework folders...
| \---etc

Der Node.js Server startet von der server.js Datei und nutzt Module (wie Express oder React) und liefert das Framework-UI (index.html) bei Aufruf von https://server/ zurück.

Die Middleware (‚E‘ - Express)

In unserem Beispiel ist nun die UI auf dem Node.js Server zunächst lauffähig. Als Nächstes sollten wir dieses UI mit unseren Dominodaten verbinden. In einer Domino-Webform würde üblicherweise ein Aufruf eines Webagenten dafür sorgen, dass durch diesen Agenten Daten an die Webform gelangen. In Node.js machen wir im Grunde genommen dasselbe. Aus unserem UI heraus greifen wir über einen http-Request auf eine API-Schnittstelle zu. Diese API-Schnittstelle erwartet einen Aufruf, kommuniziert mit Domino und liefert unsere gewünschten Daten an das Frontend zurück.

Node.js brilliert hierbei in zwei wichtigen Aufgabenbereichen – als Webserver und als API-Schnittstelle. Wir können in unserer Middleware Routen hinzufügen, welche unsere API-Aufrufe erwarten. Nehmen wir an, wir wollen eine Liste von Personen in unserem UI ausgeben. Unser Frontend führt dementsprechend einen Aufruf an die API auf demselben Node.js Server:


1
2
let uri = myDomain + "/api/people";
request.get( uri ).then( displayTheResults );

Dieser Request ruft also die Route „/api/people“ auf unserem Node.js Server auf. Aktuell existiert diese Route aber noch nicht, also fügen wir diese Route unserem Expressmodul hinzu.


1
2
3
4
app.get('/api/people', (req, res) => {
let myResults = doLookup();
res.json( myResults );
})

Diese Route wird alle Aufrufe an „yourDomain/api/people“ entgegennehmen. Danach wird unser Middlewarecode mit Domino kommunizieren und unsere Daten als JSON zurückliefern. Zudem übernehmen diese Methoden auch die Verarbeitung des JSONs, sodass ein bidirektionaler Datenversand einfach durchgeführt werden kann.
Somit kann der Server in unserem Beispiel auf API-Aufrufe antworten. Als Nächstes muss geprüft werden, wie man Daten vom Backend erhält.

Das Backend (‚D‘ - Domino)

HCL bietet über das AppDevPack ein "domino-db Node.js Modul" an, welches mithilfe von DQL Queries eine Datenbankabfrage ermöglicht.

Beispiel:


1
2
3
4
5
6
7
8
9
function doLookup() {
const { domServer } = require('domino-db');
domServer(serverConfig).then(
async (server) => {
const db = await server.useDatabase(dbConfig);
const docs = await db.bulkReadDocuments(DQLquery);
return docs;
});
}

Dieses Beispiel führt eine DQL Query aus. Die Abfrage liefert eine Menge von Dokumenten (docs), welche der Rückgabewert unserer doLookup () Methode und somit die Antwort unserer API Route sind.
In unserem Frontend erhalten wir diese Daten als JSON-Objekt, welches wir nun zur Anzeige verarbeiten und ausgeben können.

Wir haben den gesamten Stack abgebildet und zeigten auf, wie Daten als JSON-Objekt von einer Domino-Datenbank zu einer Frontendanwendung gelangen.
Dabei existieren sowohl Frontend, Expressrouten und Domino-Datenbank unabhängig voneinander und könnten so auch auf unterschiedlichen Servern liegen. Es können sogar unterschiedliche Frontend-Anwendungen auf dieselbe API zugreifen (z.B. ein Mobile- und ein Webfrontend).

Dieser Beitrag gibt einen Einblick in die Funktion einer Full-Stack-Applikation auf NERD-Architektur und wir sind gespannt, ob und wie HCL diese Technologie ausbauen wird.

Wir freuen uns auf neue und spannende Projekte und bitten um Kontaktaufnahme, wenn wir Sie unterstützen dürfen.

Tobias Krammer

Fachinformatiker Anwendungsentwicklung
  • seit 2016 bei der GFI