Serverless done right. Von der Idee zum MVP in 7 Tagen.

Keine Kommentare

Wenn Menschen mit Behinderung mit der Deutschen Bahn reisen möchten und Unterstützung benötigen, müssen sie eine so genannte Hilfeleistung anmelden. Hilfeleistungen sind z. B. der Einsatz von Zugliften für Rollstuhlfahrer oder die Begleitung zum Sitzplatz. Diese Voranmeldung ermöglicht die Planung und Organisation des Servicepersonals an den betroffenen Bahnhöfen.

Hilfeleistungen können direkt am Schalter, per Telefon, Chat oder via Online-Formular angemeldet werden. Ich persönlich möchte nicht für jeden Ticketkauf zum Schalter. Die Telefonnummer ist kostenpflichtig und die Warteschleife lang. Ob der Chat funktioniert habe ich nie getestet. Zu guter Letzt gibt es das Online-Formular. Das Formular hat annähernd 80 Felder für eine Hin- und Rückfahrt mit jeweils einem Umstieg und ist für jede Fahrt komplett auszufüllen. Viele der Felder sind immer gleich. So wird z. B. der Name, die Telefonnummer, der Grad der Behinderung uvm. immer wieder abgefragt. Daten die sich nie oder nur selten ändern.

Das Portal Hilfeleistung als Service ist eine Webanwendung, die es einfacher macht, Hilfeleistungen anzumelden. So können z. B. Online-Tickets direkt importiert werden. Die allgemeinen Daten werden einmal erfasst und dann für jede Fahrt wiederverwendet. Vielfahrer können Reisen einfach zu einem anderen Datum wiederholen. Im besten Fall ist eine Anmeldung damit in zwei Klicks erledigt. Hilfeleistung als Service erfasst darüber hinaus auch alle Statusänderungen und ordnet eingehende E-Mails den jeweiligen Hilfeleistungen zu.

Die Entwicklung von Hilfeleistung als Service stand von Anfang an unter einem strikten Zeitplan. So wollte ich die Idee innerhalb von sieben Tagen in Form eines MVPs umgesetzt haben. Um dieses ambitionierte Ziel zu erreichen, habe ich mich für eine Serverless-Architektur entschieden.

Was ist serverless?

Viele denken bei dem Begriff serverless direkt an AWS Lambda, bzw. Functions-as-a-Service. Dabei ist FaaS nur ein kleines Subset von serverless.
Des Weiteren beschränkt sich serverless nicht auf AWS, Azure oder Google Cloud. Hilfeleistung als Service nutzt keinen einzigen Service der großen Cloudanbieter.

Eine viel zutreffendere Definition von serverless ist meiner Meinung nach „less servers“. Die Idee ist, so wenig Infrastruktur und Server wie möglich selbst zu betreiben. Aber auch das ist nur die halbe Wahrheit. Im Grunde geht es um die Nutzung bestehender Services. Hier findet sich auch der wahre Nutzen: Anstatt Zeit an Dingen wie Login / Registrierung zu verschwenden, nutzt man einen bestehenden Service wie z. B. Auth0 und konzentriert sich von Anfang an direkt auf die Core Domain. Ein weiterer Vorteil ist die nutzungsbasierte Abrechnung. Alle der von Hilfeleistung als Service verwendeten Services sind zu einem gewissen Grad kostenlos. Somit habe ich nicht nur Zeit sondern auch Kosten gespart.

Die Funktionsweise von Hilfeleistung als Service im Überblick

Die Mobilitätsservice-Zentrale (MSZ) der Deutschen Bahn bietet keine offiziellen APIs an, um Hilfeleistungen anzumelden. Daher nutzt Hilfeleistung als Service zwei offen zugängliche Integrationspunkte: das Online-Formular sowie eingehende E-Mails. Durch Anbindung dieser lassen sich schon viele Use-Cases abdecken und die Anmeldung erheblich vereinfachen.

Integration des Online-Formulars

Das Online-Formular ist die einzige Möglichkeit, eine Hilfeleistung automatisiert anzumelden. Im besten Fall verläuft die Anmeldung damit ohne manuelle Arbeit auf Seiten des Antragsstellers.

Die Felder des Formulars geben eine Struktur vor. Es ist somit sehr klar definiert welche Daten gebraucht werden. Darüber hinaus verfügt das Formular über eine rudimentäre Validierung der Felder.

Das Formular wurde mit einem .NET RPC Framework implementiert. Durch reverse-engineering fand ich schnell heraus, wie der Request an das Backend aussieht. Das Problem: die Validierung des Requests passiert ausschließlich im Frontend. Aus diesem Grund entschied ich mich, das Formular automatisiert auszufüllen. Neben der Validierung hat das einen großen weiteren Vorteil: Ich kann einen Screenshot des ausgefüllten Formulars erstellen. Dies gibt mir als Betreiber Sicherheit, da ich beweisen kann, was genau abgeschickt wurde. Es dient aber auch der Verifikation und Fehleranalyse für den Benutzer, da dieser vor der Anmeldung über eine Testfunktion feststellen kann, ob alle Felder richtig ausgefüllt wurden. Bei Validierungsfehlern zeigt ein zweiter Screenshot, welche Felder fehlerhaft sind. Zu guter Letzt: wenn sich das Formular jemals inhaltlich ändert, erfahre ich davon, ohne Schaden anzurichten.

Integration eingehender E-Mails

Der zweite Integrationspunkt sind eingehende E-Mails. Die MSZ verschickt eine Reihe von E-Mails nach Anmeldung einer Hilfeleistung. Diese beinhalten z. B. Statusupdates oder Online-Tickets für reservierte Rollstuhlplätze. Durch eine automatisierte Auswertung dieser E-Mails ist es möglich, den Status einer Anmeldung zu aktualisieren.

Hilfeleistung als Service übermittelt bei jeder Anmeldung eine eindeutige, zufällig generierte E-Mail-Adresse. Bei Eingang von E-Mails wird durch Parsen des Betreffs sowie des E-Mail-Inhaltes ermittelt, ob es sich um ein Update für die Hin- bzw. Rückreise handelt. Die E-Mail wird der Hilfeleistung zugeordnet und der Status entsprechend angepasst. Derzeit werden alle eingehenden E-Mails an den Antragssteller weitergeleitet. Es wäre jedoch ein Leichtes, hier auch unwichtige E-Mails herauszufiltern.

Alle E-Mails sind im Portal in der Detailansicht der Anmeldung aufgelistet, einsehbar und Anhänge können heruntergeladen werden.

Detailansicht einer Hilfeleistung - Liste der E-Mails

Verwaltung von Fahrten

Mit diesen zwei Integrationspunkten ist es nun möglich Hilfeleistungen anzumelden und deren Status zu verfolgen. Was jetzt noch übrig bleibt, ist, das Eintragen der Fahrten so einfach wie möglich zu gestalten. Eine Hilfeleistung beinhaltet eine Hinfahrt und optional eine Rückfahrt. Eine einzelne Fahrt hat stets Informationen über die Abfahrt und Ankunft sowie ggf. vorhandene Umstiege.

Derzeit vereinfacht Hilfeleistung als Service das Anlegen von Fahrten auf drei Arten.

1. Manuelle Anlage einer Fahrt
Durch die Wiederverwendung der allgemeinen Daten sind hierbei deutlich weniger Felder auszufüllen. Von 80 Feldern müssen also nur noch knapp die Hälfte ausgefüllt werden. Dies ist bereits eine deutliche Verbesserung.

2. Wiederholen einer vergangenen Fahrt
Einmal angelegt ist es möglich, eine Fahrt zu einem späteren Zeitpunkt zu wiederholen. Hierbei wird die Fahrt ausgewählt und ein neues Datum angegeben. Das Portal ersetzt dann lediglich die Abfahrts- und Ankunftszeiten. Diese Funktion ist vor allem für Pendler relevant, die immer die gleiche Strecke fahren.

3. Importieren von Online-Tickets
Die mit Abstand schnellste Art eine Fahrt anzulegen, ist diese zu importieren. Anhand der Auftragsnummer eines Online-Tickets kann die gesamte Fahrt mitsamt der Reservierungen mit einem einzigen Klick importiert werden. Die Anmeldung der Hilfeleistung ist damit in zwei Klicks erledigt.

Es existiert immer noch ein großes Potential, das Anlegen von Fahrten weiterhin zu vereinfachen.

Welche Services nutzt Hilfeleistung als Service?

Die serverless-Architektur von Hilfeleistung als Service

Neben der Kernfunktionalität benötigt Hilfeleistung als Service jedoch auch unterstützende Funktionen wie Login, Infrastruktur zum Hosten der Single-Page Application und Dinge wie SSL-Zertifikate. Hier kommt serverless ins Spiel. Was eine Subdomäne für Hilfeleistung als Service ist, ist die Coredomäne eines anderen.

Cloudflare

Im Grunde ist Cloudflare ein Man-in-the-middle. Einmal eingebunden, wird sämtlicher Traffic über Server von CF geroutet. Daraus ergeben sich interessante Möglichkeiten wie (D-)DOS Schutz, Caching, CDN, Statistiken und vieles mehr.

Hilfeleistung als Service nutzt Cloudflare vor allem um SSL-Verschlüsselung zu gewährleisten und grobe Nutzungsstatistiken zu erfassen. Außerdem ist die Konfiguration der DNS-Einträge einfach und schnell.

Netlify

Mit Netlify lassen sich statische Webseiten unkompliziert hosten. Netlify hostet nicht nur die Single-Page-Application von Hilfeleistung als Service, sondern automatisiert auch das Deployment. Bei jedem Push in ein Git Repository baut Netlify automatisch den Client neu und stellt sicher, dass immer die neueste Version an den Browser ausgeliefert wird. Darüber hinaus leitet es alle API Requests des Clients auf das Backend um.

Auth0

Das gesamte Usermanagement von Hilfeleistung als Service wird von Auth0 übernommen. Registrierung, Password Reset, Verifikation der E-Mail-Adresse. Sogar die Eingabe des Passwortes erfolgt auf einer von Auth0 gehosteten Seite. Damit kommt Hilfeleistung als Service nie mit dem Passwort in Berührung. Die Integration im Backend erfolgt über OpenID Connect.

Mailgun

Von allen bisher vorgestellten Services ist Mailgun der wichtigste. Mailgun managed ein- sowie ausgehende E-Mails. Und das inkl. SPF, DKIM, Logs und Speicherung. Zusätzlich übernimmt Mailgun das Parsen und Aufbereiten der E-Mails. Über eine API können dann eingehende E-Mails programmatisch heruntergeladen werden.

Hilfeleistung als Service nutzt Mailgun vor allem um die E-Mails der MSZ automatisiert zu verarbeiten. Allerdings benötigt auch Auth0 einen SMTP-Account für den Versand von E-Mails. Auch hierfür wird Mailgun verwendet. Zum Beantworten von Supportanfragen nutze ich Mailgun natürlich auch.

Das Backend

Eine serverless-Architektur zu wählen bedeutet nicht, dass man keine eigenen Server mehr betreiben darf. Es gibt gute Gründe, Server für bestimmte Teile der Anwendung selbst zu betreiben.

Der NixOS Server von Hilfeleistung als Service stellt vier Services bereit:

  1. Haskell-Backend,
  2. Form-Submit-Service,
  3. Selenium Standalone-Server,
  4. PostgreSQL-Instanz

Das Haskell-Backend beinhaltet die Businesslogik und bietet eine REST API für den Client an. Der Form-Submit-Service meldet Hilfeleistungen mithilfe des Selenium-Servers an.

Der Hauptgrund, für genau diese Services einen Server zu betreiben, waren die Kosten. Während es mit vertretbarem Aufwand möglich gewesen wäre, das Backend und die PostgreSQL serverless zu betreiben, fallen spätestens für Selenium Server, die teilweise auch nur als Grids verkauft werden, sehr hohe Kosten an. Darüber hinaus verwende ich den Selenium-Server nicht zum Testen einer Webanwendung, sondern zum Ausfüllen eines Formulars. Viele der Selenium-as-a-Service-Angebote sind so stark auf das Testen ausgelegt, dass sie einfach nicht nutzbar gewesen wären. Alles in allem fand ich keine Konfiguration, die auch nur annähernd auf max. 9,99 € pro Monat gekommen wäre.

Daneben geht mit serverless deployments auch gern ein gewisser Konfigurationsaufwand einher. Man denke hier nur an AWS mit VPCs, Fargate Service Definitions, Task Definitions, Docker, und so weiter. NixOS bietet mir ein komplett deklaratives Betriebssystem. Grob gesagt gibt es eine Konfiguration, die in etwa so aussieht wie „services.postgres.enable = true„. Schon ist die PostgreSQL verfügbar. Ebenso einfach ist der Selenium-Server konfiguriert. Das hat mir einfach enorm viel Zeit gespart. Die Konfiguration des Servers ist selbstverständlich auch in einem Git-Repository als configuration-as-a-code gespeichert und versioniert.

Aufgrund der Kosten- und Zeitersparnis kam für mich ein serverless-Ansatz für genau diese Services nicht in Frage.

Lessons learned

Anfangs hatte ich den Plan, das Anmelden von Hilfeleistungen zu monetarisieren. Hierbei habe ich verschiedenste Modelle durchprogrammiert inkl. Anbindung an Stripe und PayPal. Dies hat Zeit gekostet und am Ende habe ich mich für eine spendengetriebene Finanzierung entschieden. Letzteres war eine Sache von fünf Minuten. Ich habe somit mehrere Tage Zeit verschwendet.

Viel interessanter war jedoch das Ergebnis der ersten Beta-Tests mit echten Nutzern. Da ich selbst „Kunde“ bin und Hilfeleistungen in der Vergangenheit angemeldet habe, wusste ich ungefähr wie die Integration mit der MSZ aussieht. Jedoch haben schon die ersten Betatester komplett unterschiedliche Antworten bekommen. Auch kamen direkt Anforderungen an das Portal auf, die ich so nicht bedacht hatte. Ganz klares Signal: Endbenutzer müssen so früh wie möglich, wenn nicht sogar von Anfang an, einbezogen werden. Schnelle Entwicklung bedeutet vor allem auch, dass man sehr einfach schnell in die falsche Richtung entwickeln kann.

Die für mich wichtigste Lession Learned habe ich allerdings nicht bei der Entwicklung von Hilfeleistung als Service gelernt, sondern im Kundenprojekt. Serverless-Cloud-Lösungen sind zu kompliziert, um schnell gute Ergebnisse zu liefern. Dieses Wissen habe ich hier direkt angewandt. Das Ergebnis war der NixOS-Server. Anstatt Tage damit zu verschwenden, die Services mit Gewalt in der Cloud abzubilden, habe ich mich direkt für einen selbstbetriebenen Server entschieden.

Fazit

Serverless richtig angewendet kann die Entwicklung einer Softwarelösung unheimlich beschleunigen. Es ermöglicht die Konzentration auf die Core Domain, also auf die reine Wertschöpfung. Zeit an unterstützender Funktionalität wird an externe ausgelagert.

Die Entwicklung von Hilfeleistung als Service war nach neun Tagen so weit, dass sie von Betatestern getestet werden konnte. Mit realen Anmeldungen von Hilfeleistungen. Der Durchstich war einmal quer durch alle Integrationspunkte. Ein komplett funktionierender MVP. Danach habe ich in drei Wochen das Portal weiter verbessert und um viele Features ergänzt. Ohne serverless wäre dieser Zeitplan utopisch gewesen.

Mittlererweile hat Hilfeleistung als Service 50 Nutzer und ebensoviele Anmeldungen von Hilfeleistungen. Ein Flop? Vielleicht. Aber definitiv ein starkes Signal an die Deutsche Bahn, wie das Anmelden von Hilfeleistungen aussehen könnte und sollte.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.