13 · Eine App mit Server dahinter
daten von "https://lieferung.deine-domain.de"Eine Zeile, und aus einem Programm wird eine Gegenstelle: Sie rechnet weiterhin selbst — Seiten, Listen, Bedingungen, Sortierung —, holt den Bestand aber von einem Fibel-Server und schickt Änderungen dorthin zurück.
Es ist dieselbe .fibel-Datei wie auf dem Server. Der einzige Unterschied ist die daten-Zeile.
Wofür das gedacht ist
Der Fall, für den es gebaut wurde, ist eine Liefer-App:
- Im Büro läuft
fibel starte lieferungauf einem Server. Dort legt jemand Sendungen an, dort liegen die Daten, dort ist das Protokoll. - Auf dem Telefon läuft dieselbe App als APK. Der Fahrer meldet sich an, sieht seine Tour, lässt unterschreiben — und der Beleg ist sofort im Büro.
Dasselbe im Browser: fibel baue --out app erzeugt einen Ordner, der auf jedem Webspace liegen kann und seine Daten von deinem Server holt.
Kein Server auf dem Gerät
Ein häufiges Missverständnis, deshalb ausdrücklich:
Telefon dein Server
┌────────────────────────────┐ ┌──────────────────┐
│ Compose zeichnet │ │ fibel starte │
│ WebView rechnet (zeigt │ HTTPS ──► │ lieferung.fibel │
│ nichts, lauscht auf │ ◄────── │ Daten, Rechte │
│ nichts) │ │ │
└────────────────────────────┘ └──────────────────┘Der WebView in der App ist nur die JavaScript-Maschine, die Android ohnehin mitbringt. Er zeigt nichts an und nimmt keine Verbindungen entgegen. Gerechnet wird auf dem Gerät, gezeichnet wird mit echten Android-Bedienelementen — nur die Wahrheit liegt auf dem Server.
Was der Server dafür anbietet
Nichts, was du einschalten müsstest. Jeder laufende Fibel-Server kann es:
GET /__daten | alles, was der Angemeldete sehen darf |
POST /__do/… | dieselben Aktionen wie ein Formular, nur mit JSON-Antwort |
OPTIONS auf beide | die Freigabe für eine App unter einer anderen Adresse |
Erkannt wird eine solche Anfrage am Kopf X-Fibel: 1. Ohne den antwortet der Server wie bisher mit Seiten.
Andere Adresse. Die App im Browser liegt fast immer woanders als der Server, die im Telefon sowieso. Deshalb gibt der Server genau diese beiden Wege für jede Adresse frei (Access-Control-Allow-Origin: *). Das ist ungefährlich: Dabei schickt ein Browser keine Kekse mit, und die Sitzungsmarke hat nur die App selbst. Seiten und Formulare bleiben, wie sie sind.
Nur mit https://. Android lässt eine App nicht über http:// sprechen, und eine Seite, die über https:// kommt, darf keinen http://-Server fragen. Zum Ausprobieren auf dem eigenen Rechner geht http://localhost.
Es entsteht dabei kein zweiter Weg an den Rechten vorbei. Die Gegenstelle benutzt dieselbe gefilterte Sicht und dieselben Aktionen wie eine Seite: Was jemand im Browser nicht sähe, bekommt er auch hier nicht, und was er nicht ändern dürfte, wird auch hier abgelehnt. Das ist keine Zusage, sondern eine Folge des Aufbaus — es gibt schlicht keinen anderen Weg zu den Daten.
Anmelden ohne Keks
Eine App hat keinen Keksbehälter. Sie bekommt beim Anmelden eine Sitzungsmarke im Rumpf und schickt sie fortan im Kopf X-Fibel-Sitzung mit.
Dabei entfällt die Marke gegen fremde Formulare — und zwar aus einem Grund, nicht aus Bequemlichkeit: Ein Browser schickt den Sitzungskeks bei jeder Anfrage automatisch mit, auch bei einer, die eine fremde Seite ausgelöst hat. Deshalb braucht es dort den Beweis, dass die Anfrage von hier kam. Einen eigenen Kopf kann eine fremde Seite gar nicht setzen.
Wer sich mit dem Keks anmeldet, wird auch mit X-Fibel weiterhin wie ein Formular behandelt. Sonst ließe sich der Schutz mit einem zusätzlichen Kopf umgehen.
Ohne Anmeldung: nur lesen
Eine App mit daten von ändert nur mit Anmeldung. Ohne Konten — kein modell Nutzer — liest sie den Bestand, aber sie legt nichts an, ändert und löscht nichts. Der Server antwortet dann:
Ohne Anmeldung nimmt der Server keine Änderungen von einer App an.Dasselbe gilt für Gäste auf einer öffentlichen Seite einer App mit Konten. fibel prüfe meldet beides, bevor es jemandem auffällt — und ohne Netz steht die Änderung später mit genau diesem Grund in „Nicht übertragen“.
Lesen darf ein Gast, was auf öffentlichen Seiten steht. Hat die App Konten, bekommt er über /__daten genau die Modelle, die auf einer Seite mit oeffentlich vorkommen — durch dieselbe gefilterte Sicht wie im Browser. Alles andere kommt leer zurück, auch das Konten-Model, solange keine öffentliche Seite es auflistet.
Die Begründung ist dieselbe wie beim Anlegen: Eine Seite ist ein Versprechen. Was ein Gast im Browser ohnehin sähe, darf er auch hier lesen — mehr nicht. Sonst zeigte die App einer Gaststätte ihre Speisekarte erst nach der Anmeldung.
Nicht mitgezählt wird, was hinter einem wenn steht: Das hängt an Werten, die es erst beim Zeichnen gibt. Wer einem Gast etwas zeigen will, stellt es unbedingt auf eine öffentliche Seite.
Das ist eine Entscheidung, keine Lücke. Die naheliegende Lockerung wäre: Eine Anfrage ohne Sitzung braucht keine Formularmarke, denn ohne Keks gibt es niemanden, in dessen Namen eine fremde Seite handeln könnte. Für sich genommen stimmt das. Aber die Wege einer Gegenstelle sind für jede Adresse freigegeben, damit Apps im Browser und im Telefon sie erreichen. Beides zusammen hieße: Jede Webseite im Netz könnte die Browser ihrer Besucher anonym bei deinem Server schreiben lassen. Die Bremse zählt ohne Anmeldung je Internet-Adresse — über tausend Besucher verteilt, hielte sie nichts mehr auf.
Formulare für Gäste — ein Kontaktformular, ein Gästebuch — gehen weiterhin, als gewöhnliche Seite des Servers statt als App mit daten von.
Was passiert, wenn das Netz weg ist
Die App arbeitet weiter. Nichts davon muss man einschalten.
- Sie startet ohne Netz, mit dem letzten Stand. Der liegt im Gerät — im Browser im Speicher der Seite, im Telefon in der Datei der App — und übersteht, dass die App geschlossen wird. Angemeldet bleibt man auch.
- Sie nimmt Änderungen an. Wer im Keller eine Lieferung abhakt, sieht sie sofort abgehakt, samt allem, was
= jetztund= ichdazutun. - Sie reicht nach, der Reihe nach, sobald das Netz zurück ist: beim nächsten Neuholen (↻), wenn der Browser meldet, dass er wieder online ist, und sonst von selbst in wachsenden Abständen. Ein Eintrag, der ohne Netz angelegt und gleich wieder geändert wurde, kommt als genau das an — angelegt, dann geändert.
- Nichts kommt doppelt an. Jede Änderung trägt eine Auftragsnummer (
X-Fibel-Auftrag). Ging nur die Antwort verloren und die App schickt noch einmal, erkennt der Server den Auftrag und führt ihn kein zweites Mal aus.
Solange es etwas zu sagen gibt, steht eine schmale Leiste da: „Kein Netz · 2 Änderungen warten“. Ist alles angekommen, verschwindet sie.
Was der Server ablehnt
Ohne Netz weiß die App nicht, ob eine Änderung erlaubt ist. Das weiß nur der Server, und er entscheidet erst beim Nachreichen — vielleicht wurde der Eintrag inzwischen gelöscht, vielleicht hat sich ein Recht geändert.
Solche Änderungen verschwinden nicht still. Sie stehen in der Leiste unter „Nicht übertragen“: was geändert werden sollte, und warum es nicht ging. Dort bleiben sie, auch über einen Neustart, bis man sie verwirft.
Mit Netz gibt es diese Liste nicht. Da kommt eine Ablehnung sofort zurück, wie gewohnt.
Keine Ablehnung ist eine Antwort wie „Server gerade nicht erreichbar“ (502, 503, 504) oder „zu schnell“ (429). Dann wartet die Änderung einfach weiter.
Wenn zwei denselben Eintrag ändern
Es gilt, was zuletzt beim Server ankommt. Geändert werden dabei nur die Felder, die das Formular schickt: Setzt der Fahrer ohne Netz den Status und das Büro inzwischen die Adresse, steht danach beides da. Ändern beide dasselbe Feld, gewinnt, wessen Änderung später ankommt — auch wenn sie früher getippt wurde.
Das ist einfach zu erklären und verliert nie still eine ganze Änderung. Wer ein Feld nur unter einer Bedingung ändern lassen will, schreibt schreibbar daran (Kapitel 5). Dann lehnt der Server ab, statt zu überschreiben — und die Ablehnung steht in „Nicht übertragen“.
Wem wartende Änderungen gehören
Der Person, die sie gemacht hat. Meldet sie sich ab, verschwindet der Stand vom Bildschirm, die wartenden Änderungen bleiben im Gerät. Meldet sich dort jemand anderes an, schickt die App nichts in fremdem Namen — erst, wenn die erste Person wieder angemeldet ist.
Laden ohne Netz
- Im Telefon bringt die App alles mit, was sie zum Starten braucht.
- Im Browser legt
fibel baueeinsw.jsin den Ordner. War die App einmal überhttps://offen, lädt sie danach auch ohne Netz. Aus einer Datei geöffnet (file://) geht das nicht.
Wieviel geholt wird
Alles, was der Angemeldete sehen darf — auf einmal, nicht seitenweise. Das ist die Entscheidung, die daten von ausmacht: Die App rechnet selbst und braucht dafür alles, was sie zeigen könnte.
Für eine Liefertour, ein Auftragsbuch, eine Mitgliederliste ist das genau richtig. Für einen Katalog mit hunderttausend Artikeln ist es das nicht — dann gehört das Rechnen auf den Server, und die App wäre besser eine Webseite.
Die Sichtregel hilft dabei mehr, als man denkt: sichtbar eintrag.fahrer == ich sorgt dafür, dass ein Fahrer seine Tour bekommt und nicht die von dreißig anderen.
In der App
- Die Anmeldung fragt nach einem Passwort, sobald ein Server dahintersteht. Rechnet die App für sich allein, genügt ein Name — es gibt niemanden, vor dem zu schützen wäre.
- In der Kopfzeile steht ein ↻ zum Neuholen. Was noch wartet, geht dabei zuerst hin.
- Fehlermeldungen des Servers werden angezeigt, statt dass ein Knopf scheinbar nichts tut.
- Unter der Kopfzeile steht die Leiste für „Kein Netz“, wartende Änderungen und „Nicht übertragen“ — nur, solange es etwas zu sagen gibt.
- Ins Paket kommt bei
daten vonkein Bestand und kein Upload (Kapitel 12).
Was noch fehlt
- Keine Benachrichtigung, wenn sich auf dem Server etwas ändert. Die App merkt es beim nächsten Holen. Im Browser gibt es dafür die leise Verbindung (
/__live); für die App wäre das ein eigener Weg. - Dateien gehen voraus. Ein Foto oder eine Unterschrift geht an den Server, sobald es entsteht. Ohne Netz bleibt es im Browser liegen und ist sofort zu sehen; beim Nachreichen geht es vor der Änderung hinaus, zu der es gehört, und der Eintrag bekommt den richtigen Pfad. Wird die Seite vorher neu geladen, ist die wartende Datei weg — dann steht die Änderung mit „Die Datei ist nicht mehr da“ in „Nicht übertragen“, statt auf nichts zu zeigen. Die Rechteprüfung an der Datei gilt wie immer (Kapitel 5).
- In der App wählt man eine Datei über die Auswahl von Android und unterschreibt mit dem Finger; beides geht sofort zum Server. Ohne Netz nimmt sie es dort nicht an — anders als im Browser wartet im Gerät nichts.
Zurück zur Übersicht