java\06_Schnittstellen_Datenformate\ (nur JDK, keine Bibliotheken).
Schnittstellen und Datenformate kamen in 8 von 9 Prüfungen vor, fast immer in Teil 1 als eine Teilaufgabe von 6 bis 25 Punkten. Die Fragen sind meist Wissens- und Verständnisfragen („Erläutern Sie …“, „Beschreiben Sie die Parameter …“), dazu kommen Anwendungsaufgaben: XML-Fehler anhand einer DTD finden, Tabellen in JSON überführen, eine HTTP-Antwort im Code zusammenbauen. Einen Belegsatz mit Notationshilfen gibt es für diesen Block nicht – Syntax und Begriffe musst du selbst können.
| Unterthema | Kategorie | Typische Punkte | Wichtigste Fähigkeit |
|---|---|---|---|
| SD-01 XML | Meistens (JSON/XML) | 6–13 | wohlgeformt vs. gültig, Fehler anhand einer DTD finden, Grenzen der Schema-Validierung |
| SD-02 JSON | Meistens (JSON/XML) | 7–14 | Tabellen fehlerfrei in JSON überführen, Embedding vs. Referenz, JSON im Code erzeugen |
| SD-03 REST & HTTP-Methoden | Oft ↑ (REST/HTTP) | 2–12 | REST-Konzept erläutern, CRUD ↔ HTTP-Methoden, Endpunkte entwerfen |
| SD-04 HTTP-Request/Response | Oft ↑ (REST/HTTP) | 2–10 | Aufbau von Request und Response, Statuscodes, URL-Parameter, Antwort im Code bauen |
| SD-05 eRechnung | Sonstige ⚠ | ca. 18 (W25) | Ziel, Formate, Pflichten, Validierung, Datenschutz – oft mit englischem Text |
Punkte des Blocks je Prüfung: W21 2 · S22 – · W22 13 · S23 13 · W23 14 · S24 25 · W24 18 · W25 24 · S26 12.
Vorkommen: JSON/XML zusammen 6/9 (W22, S23, W23, S24, W24, W25) · XML konkret: W22 T1 A3c (13 P: Zweck der DTD, wohlgeformt/gültig, Fehler finden), W25 T1 A3bc (6 P: warum Schema-Validierung nicht reicht); eRechnungen (W25) sind XML-Dokumente
XML (Extensible Markup Language) ist eine textbasierte Auszeichnungssprache für hierarchisch strukturierte Daten. Sie ist für Menschen und Maschinen lesbar, plattform- und programmiersprachenunabhängig und wird vor allem für den Datenaustausch zwischen Systemen verwendet (eRechnung, Behördenstandards, SOAP-Webservices, Konfigurationsdateien, Office-Dateiformate). Anders als HTML gibt XML keine Elementnamen vor („extensible“): Die Namen legt man selbst fest. Welche Elemente in welcher Reihenfolge erlaubt sind, beschreibt eine DTD oder ein XML-Schema (XSD).
Beispiel: Spielplan eines Stadttheaters (die Zeilennummern gehören nicht zum Dokument).
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE spielplan SYSTEM "spielplan.dtd"> 3 <!-- Spielplan des Stadttheaters (Auszug) --> 4 <spielplan saison="2026/27"> 5 <vorstellung id="v1" saal="gross"> 6 <stueck>Der Besuch der alten Dame</stueck> 7 <datum>2026-11-14</datum> 8 <preis>32.00</preis> 9 </vorstellung> 10 <vorstellung id="v2" saal="studio" ausverkauft="ja"> 11 <stueck>Momo</stueck> 12 <datum>2026-11-15</datum> 13 <preis>12.50</preis> 14 <hinweis>ab 8 Jahren</hinweis> 15 <hinweis>Einführung 19:15 Uhr</hinweis> 16 </vorstellung> 17 </spielplan>
| Bestandteil | Beispiel (Zeile) | Erklärung |
|---|---|---|
| Prolog / XML-Deklaration | <?xml version="1.0" encoding="UTF-8"?> (1) | nennt XML-Version und Zeichenkodierung; optional, muss aber – wenn vorhanden – ganz am Anfang stehen |
| Dokumenttyp-Deklaration | <!DOCTYPE spielplan SYSTEM "spielplan.dtd"> (2) | verweist auf die DTD, gegen die geprüft wird; der Name muss dem Wurzelelement entsprechen |
| Kommentar | <!-- … --> (3) | wird vom Parser ignoriert |
| Wurzelelement | <spielplan> … </spielplan> (4–17) | genau ein Element umschließt alle anderen |
| Element | <stueck>Momo</stueck> (11) | Start-Tag, Inhalt, End-Tag; Inhalt = Text und/oder Kindelemente |
| leeres Element | <pause/> | Kurzform für <pause></pause> |
| Attribut | saal="studio" (10) | Name-Wert-Paar im Start-Tag; Wert immer in Anführungszeichen; jeder Attributname höchstens einmal je Element |
| Textinhalt | 32.00 (8) | ohne Schema ist alles Text – „32.00“ ist für den Parser eine Zeichenkette |
| Entität | < > & " ' | Ersatz für Sonderzeichen, z. B. Hansen & Söhne |
Element oder Attribut? Faustregel: Attribute für Kennungen und kurze Metadaten (id, saal, einheit), Elemente für die eigentlichen Daten – und immer dann, wenn ein Wert mehrfach vorkommen oder selbst Struktur haben kann (Attribute sind nicht wiederholbar und nicht verschachtelbar).
Namensräume (namespaces) verhindern Namenskonflikte, wenn Elemente aus verschiedenen Vokabularen in einem Dokument zusammenkommen. Ein Namensraum wird durch eine eindeutige URI bezeichnet (sie muss nicht abrufbar sein) und entweder als Standardnamensraum (xmlns="…") oder mit Präfix (xmlns:cbc="…", Elemente dann <cbc:ID>) deklariert. eRechnungen im UBL-Format nutzen z. B. die Präfixe cbc und cac (Beispiel in SD-05).
Regeln der Wohlgeformtheit (Syntax)
<x/>)<a><b></b></a>, nicht <a><b></a></b><Preis> ≠ <preis>< und & im Text nur als Entität_, keine LeerzeichenZusätzlich für die Gültigkeit (gegen DTD/XSD)
ID im ganzen Dokument eindeutig<name>…</Name>) ist ein Wohlgeformtheitsfehler, kein Gültigkeitsfehler. Ein Element, das die DTD nicht kennt, ist dagegen ein Gültigkeitsfehler – syntaktisch ist es in Ordnung.Die DTD ist die Grammatik (der Bauplan) eines Dokumenttyps: Sie legt fest, welche Elemente und Attribute vorkommen dürfen, in welcher Reihenfolge und wie oft. Wofür? Damit Sender und Empfänger eine gemeinsame, verbindliche Struktur haben (Schnittstellenvertrag) und eingehende Dokumente automatisch geprüft (validiert) werden können, bevor sie verarbeitet werden. Die DTD kann im Dokument stehen (interne DTD in <!DOCTYPE spielplan [ … ]>) oder – wie oben – in einer externen Datei, auf die die DOCTYPE-Deklaration mit SYSTEM "datei.dtd" verweist; so können viele Dokumente dieselbe DTD nutzen.
1 <!ELEMENT spielplan (vorstellung+)> 2 <!ATTLIST spielplan saison CDATA #REQUIRED> 3 <!ELEMENT vorstellung (stueck, datum, preis, hinweis*)> 4 <!ATTLIST vorstellung id ID #REQUIRED 5 saal (gross|studio) "gross" 6 ausverkauft (ja|nein) #IMPLIED> 7 <!ELEMENT stueck (#PCDATA)> 8 <!ELEMENT datum (#PCDATA)> 9 <!ELEMENT preis (#PCDATA)> 10 <!ELEMENT hinweis (#PCDATA)>
| Schreibweise | Bedeutung |
|---|---|
| (a, b, c) | Sequenz: genau in dieser Reihenfolge |
| (a | b) | Auswahl: entweder a oder b |
| a | genau einmal (1) |
| a? | optional, höchstens einmal (0..1) |
| a* | beliebig oft, auch keinmal (0..n) |
| a+ | mindestens einmal (1..n) |
| (#PCDATA) | nur Text (parsed character data) |
| EMPTY / ANY | leeres Element / beliebiger Inhalt |
| Teil | Möglichkeiten |
|---|---|
| Typ | CDATA beliebiger TextID im Dokument eindeutig (Wert beginnt mit Buchstabe)IDREF verweist auf eine ID(w1|w2|w3) Aufzählung erlaubter Werte |
| Vorgabe | #REQUIRED Pflichtattribut#IMPLIED optional, ohne Standardwert"wert" Standardwert, wenn das Attribut fehlt#FIXED "wert" fester Wert |
Kardinalitäten gelten auch für Gruppen: (telefon | email)+ heißt „mindestens ein Kontakt, jeweils Telefon oder E-Mail“. Lies die DTD aus Zeile 3 so: Eine Vorstellung besteht aus genau einem Stück, dann genau einem Datum, dann genau einem Preis, danach beliebig vielen Hinweisen – genau in dieser Reihenfolge.
Beispiel: Auszug mit Fehlern, geprüft gegen die Spielplan-DTD von oben.
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE spielplan SYSTEM "spielplan.dtd"> 3 <spielplan saison="2026/27"> 4 <vorstellung id="v3" saal="foyer"> 5 <datum>2026-11-20</datum> 6 <stueck>Faust</stueck> 7 <preis>18.00</preis> 8 </vorstellung> 9 <vorstellung id="v3"> 10 <stueck>Woyzeck</Stueck> 11 <datum>2026-11-21</datum> 12 <preis>21.00</preis> 13 </vorstellung> 14 </spielplan>
| Zeile | Beschreibung | Eigenschaft |
|---|---|---|
| 4 | saal="foyer" ist kein erlaubter Wert der Aufzählung (gross|studio) | Gültigkeit |
| 5–6 | datum steht vor stueck; die DTD verlangt (stueck, datum, preis, hinweis*) | Gültigkeit |
| 9 | id="v3" ist bereits in Zeile 4 vergeben; Werte vom Typ ID müssen eindeutig sein | Gültigkeit |
| 10 | End-Tag </Stueck> passt nicht zum Start-Tag <stueck> (Groß-/Kleinschreibung) | Wohlgeformtheit |
Ein XML-Schema (XML Schema Definition, Dateiendung .xsd) erfüllt denselben Zweck wie eine DTD, ist aber selbst ein XML-Dokument und deutlich mächtiger: Es kennt Datentypen, Wertebereiche, genaue Mindest- und Höchstanzahlen und Namensräume. eRechnungen (UBL, CII) werden mit XSD-Dateien beschrieben. Dasselbe Spielplan-Format als XSD:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 3 <xs:element name="spielplan"> 4 <xs:complexType> 5 <xs:sequence> 6 <xs:element ref="vorstellung" maxOccurs="unbounded"/> 7 </xs:sequence> 8 <xs:attribute name="saison" type="xs:string" use="required"/> 9 </xs:complexType> 10 </xs:element> 11 <xs:element name="vorstellung"> 12 <xs:complexType> 13 <xs:sequence> 14 <xs:element name="stueck" type="xs:string"/> 15 <xs:element name="datum" type="xs:date"/> 16 <xs:element name="preis" type="betrag"/> 17 <xs:element name="hinweis" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> 18 </xs:sequence> 19 <xs:attribute name="id" type="xs:ID" use="required"/> 20 <xs:attribute name="saal" type="xs:string" default="gross"/> 21 <xs:attribute name="ausverkauft" type="xs:string"/> 22 </xs:complexType> 23 </xs:element> 24 <xs:simpleType name="betrag"> 25 <xs:restriction base="xs:decimal"> 26 <xs:minInclusive value="0"/> 27 <xs:fractionDigits value="2"/> 28 </xs:restriction> 29 </xs:simpleType> 30 </xs:schema>
| XSD | Bedeutung | DTD |
|---|---|---|
| <xs:element name="x" type="xs:string"/> | Element mit Datentyp | (#PCDATA) |
| xs:string, xs:integer, xs:decimal, xs:boolean, xs:date, xs:dateTime | eingebaute Datentypen (xs:date = JJJJ-MM-TT, xs:decimal mit Dezimalpunkt) | – (alles Text) |
| ohne Angabe | minOccurs = maxOccurs = 1, also genau einmal | a |
| minOccurs="0" | optional | a? |
| minOccurs="0" maxOccurs="unbounded" | beliebig oft | a* |
| maxOccurs="unbounded" | mindestens einmal | a+ |
| minOccurs="2" maxOccurs="5" | zwei bis fünf Mal | nicht möglich |
| <xs:sequence> / <xs:choice> | feste Reihenfolge / Auswahl | , / | |
| use="required" | Pflichtattribut | #REQUIRED |
| <xs:restriction> mit minInclusive, maxLength, pattern, enumeration | eigener, eingeschränkter Datentyp (z. B. Betrag ≥ 0 mit 2 Nachkommastellen) | nur Aufzählung bei Attributen |
| Kriterium | DTD | XSD |
|---|---|---|
| Schreibweise | eigene Syntax | selbst XML – mit XML-Werkzeugen bearbeit- und prüfbar |
| Datentypen | keine, alles ist Text | viele eingebaute Typen, eigene Typen mit Einschränkungen |
| Anzahl | nur ? * + | beliebige Mindest-/Höchstwerte |
| Namensräume | nicht unterstützt | unterstützt |
| Aufwand | kurz und einfach | umfangreicher, aber genauer |
DTD und XSD prüfen Struktur und (nur XSD) Datentypen einzelner Felder. Sie prüfen nicht, ob die Inhalte fachlich zueinander passen. Am Spielplan-Beispiel:
| Fehler im Dokument | DTD | XSD | Wer findet ihn? |
|---|---|---|---|
<datum>14.11.2026</datum> oder 2026-02-30 | nein | ja (kein xs:date) | Schema |
<preis>-5.00</preis> | nein | ja, mit minInclusive | Schema |
| Vorstellung liegt außerhalb der Saison 2026/27 | nein | nein | Geschäftsregel |
| Ermäßigter Preis ist höher als der Normalpreis | nein | nein | Geschäftsregel |
Für solche logischen Fehler braucht man zusätzlich Geschäftsregeln: Plausibilitätsprüfungen im Programmcode, Regeln in Schematron (XML-basierte Regelsprache mit XPath-Ausdrücken, z. B. <sch:assert test="gesamt = sum(position/betrag)">), Unit-Tests mit Testdokumenten und – bei Standards wie der eRechnung – den offiziellen Validator, der Schema und Schematron prüft.
|, ?, *, +, ID #REQUIRED und #IMPLIED.Vorkommen: JSON/XML zusammen 6/9 · JSON konkret: S23 T1 A4cb (JSON-Sensordaten in ein Relationenmodell übernehmen), W23 T1 A3c (14 P: Tabellen in JSON überführen, Embedding), S24 T1 A2c (JSON-Body eines Requests), W24 T1 A2c (8 P: Skript mit JSON-Ausgabe)
JSON (JavaScript Object Notation) ist ein schlankes, textbasiertes Datenaustauschformat. Es ist das Standardformat von REST-APIs und dokumentenorientierten NoSQL-Datenbanken (z. B. MongoDB). Medientyp: application/json, Zeichenkodierung UTF-8. JSON kennt genau sechs Arten von Werten:
| Typ | Schreibweise | Beispiel |
|---|---|---|
| Objekt | { "schlüssel": wert, … } – ungeordnete Menge von Schlüssel-Wert-Paaren | {"kursNr": 101, "titel": "Rückenfit"} |
| Array | [ wert, wert, … ] – geordnete Liste beliebiger Werte | ["MO", "MI", "FR"] |
| String | in doppelten Anführungszeichen | "Rückenfit", "2026-09-07" |
| Zahl | ohne Anführungszeichen, Dezimalpunkt, optional mit Exponent | 12, 45.00, -3.5, 1.2e3 |
| Boolean | true oder false (klein geschrieben) | "ausgebucht": false |
| null | null – „kein Wert vorhanden“ | "start": null |
Objekte und Arrays lassen sich beliebig verschachteln. Schlüssel sind immer Strings in doppelten Anführungszeichen. Ein Datum hat keinen eigenen Typ – es wird als String geschrieben, üblich im ISO-Format "JJJJ-MM-TT".
Beispiel: Die Tabelle Kurs eines Sportvereins …
| kursNr | titel | trainerin | plaetze | ausgebucht | beitrag | start |
|---|---|---|---|---|---|---|
| 101 | Rückenfit | Meyer | 12 | nein | 45.00 | 2026-09-07 |
| 102 | Yoga am Abend | Öztürk | 15 | ja | 60.00 | (leer) |
… als JSON-Dokument mit einem Array kurse:
{
"kurse": [
{ "kursNr": 101, "titel": "Rückenfit", "trainerin": "Meyer", "plaetze": 12,
"ausgebucht": false, "beitrag": 45.00, "start": "2026-09-07" },
{ "kursNr": 102, "titel": "Yoga am Abend", "trainerin": "Öztürk", "plaetze": 15,
"ausgebucht": true, "beitrag": 60.00, "start": null }
]
}
'titel') oder Schlüssel ohne Anführungszeichen (titel: …) – erlaubt ist nur "titel"[1, 2, 3,]) oder fehlendes Komma zwischen zwei Paaren45,00) statt Dezimalpunkt – das Komma trennt in JSON Elemente!True, FALSE, NULL, undefined – nur true, false, null sind erlaubt//, /* */) gibt es in JSON nicht007) sind ungültig – Postleitzahlen, Telefonnummern und IDs mit führender Null daher als String: "plz": "01067""titel": "Kurs \"Fit ab 60\"""plaetze": "12") sind zwar gültiges JSON, aber dann ein String – in Prüfungen wird auf passende Datentypen geachtet.{…}, jede Spalte ein Schlüssel (Spaltennamen übernehmen, sofern nichts anderes verlangt ist).[…], meist mit sprechendem Namen: {"kurse": [ … ]}.true/false, leere Zelle → null.Der umgekehrte Weg (S23 T1 A4cb: JSON-Sensordaten in ein Relationenmodell übernehmen): Jedes wiederkehrende Objekt wird eine Entität/Tabelle, ein eingebettetes Array wird eine eigene Tabelle mit Fremdschlüssel auf das übergeordnete Objekt.
In einer dokumentenorientierten Datenbank (Sammlungen von JSON-Dokumenten statt Tabellen) gibt es zwei Möglichkeiten, eine 1:n-Beziehung abzubilden. Beispiel: Abteilungen eines Sportvereins und ihre Trainingszeiten.
Referenz – Dokument in der Sammlung „abteilungen“
{ "abteilungId": 3, "name": "Handball", "leitung": "K. Brandt" }
Referenz – Dokumente in der Sammlung „trainingszeiten“ (verweisen über abteilungId)
[
{ "zeitId": 31, "abteilungId": 3, "tag": "MO", "von": "18:00", "halle": "Sporthalle Nord" },
{ "zeitId": 32, "abteilungId": 3, "tag": "DO", "von": "19:30", "halle": "Sporthalle Nord" }
]
Embedding – ein Dokument in der Sammlung „abteilungen“
{
"abteilungId": 3,
"name": "Handball",
"leitung": "K. Brandt",
"trainingszeiten": [
{ "tag": "MO", "von": "18:00", "halle": "Sporthalle Nord" },
{ "tag": "DO", "von": "19:30", "halle": "Sporthalle Nord" }
]
}
| Einbetten (Embedding) | Referenzieren | |
|---|---|---|
| Aufbau | zugehörige Datensätze als Array/Objekt im übergeordneten Dokument | eigene Dokumente; Verbindung über eine ID (wie ein Fremdschlüssel) |
| Lesen | eine Abfrage liefert alles – schnell | mehrere Abfragen bzw. Verknüpfung (Lookup) nötig |
| gut geeignet, wenn … | 1:1 oder 1:wenige; die Daten werden fast immer zusammen gelesen und gehören nur zu diesem Elternobjekt (z. B. die Trainingszeiten einer Abteilung) | sehr viele oder unbegrenzt wachsende Einträge; n:m-Beziehungen; Daten werden von vielen Dokumenten genutzt oder unabhängig geändert (z. B. Mitglieder, die in mehreren Abteilungen trainieren) |
| Nachteil | Redundanz und Änderungsaufwand, wenn dieselben Daten in vielen Dokumenten stecken; Dokumente können sehr groß werden | mehr Abfragen; die Konsistenz der Verweise muss die Anwendung sichern (keine Fremdschlüssel-Constraints) |
Manchmal soll ein Skript oder eine Funktion ihr Ergebnis als JSON ausgeben (W24 T1 A2c). In der Praxis erledigen das Bibliotheken (z. B. Jackson oder Gson in Java), in der Prüfung baut man den Text meist selbst zusammen. Dabei kommt es auf drei Dinge an: Klammern öffnen und schließen, Kommas nur zwischen den Elementen, Strings in Anführungszeichen (im Code als \" maskiert). Beispiel: Namen aus einem Array als JSON-Array ausgeben.
funktion namenAlsJson(namen : string[]) : string
json : string := "["
zähle i von 0 bis namen.length - 1
wenn i > 0 dann
json := json + ", " // Komma nur ZWISCHEN den Elementen
Ende wenn
json := json + "\"" + namen[i] + "\"" // Wert in Anführungszeichen
Ende zähle
json := json + "]"
rückgabe json
Ende funktion
Ergebnis für ["Anna", "Ben", "Cem"]: ["Anna", "Ben", "Cem"]; für ein leeres Array: []. Zahlen und true/false werden ohne Anführungszeichen angehängt.
i > 0 setzt dann ein Komma zu viel. Man braucht eine andere Art, sich zu merken, ob schon etwas ausgegeben wurde.| Kriterium | JSON | XML |
|---|---|---|
| Aufbau | Objekte, Arrays, Schlüssel-Wert-Paare | Elemente mit Start-/End-Tags, Attribute, Baum |
| Datentypen | String, Zahl, Boolean, null eingebaut | ohne Schema nur Text; Typen erst über XSD |
| Datenmenge | gering (keine End-Tags) | größer (jeder Name steht doppelt) |
| Verarbeitung | direkt in Objekte von JavaScript/Java/C# abbildbar, schnell zu parsen | DOM-/SAX-Parser, XPath, XSLT |
| Prüfung | JSON Schema (weniger verbreitet) | DTD, XSD, Schematron – sehr ausgereift |
| Kommentare, Namensräume | nein | ja |
| typischer Einsatz | REST-APIs, Web und Apps, NoSQL-Datenbanken | eRechnung, Behördenstandards, SOAP, Office-Formate, Dokumente |
CSV (Comma-Separated Values): eine Textzeile je Datensatz, Werte durch Trennzeichen getrennt (in Deutschland oft ;), erste Zeile meist mit Spaltennamen. Keine Hierarchie, keine Datentypen, Probleme bei Trennzeichen im Text. Einsatz: Tabellen-Export und -Import.
kursNr;titel;plaetze 101;Rückenfit;12 102;Yoga am Abend;15
YAML: Struktur über Einrückung, Kommentare mit #, sehr gut lesbar. Einsatz vor allem für Konfigurationsdateien (Docker Compose, CI/CD-Pipelines). Fast jedes JSON-Dokument ist auch gültiges YAML.
kurs: kursNr: 101 titel: Rückenfit tage: [MO, MI] # Kommentar erlaubt
Vorkommen: REST/HTTP zusammen 4/9 (W21, S24, W24, S26), davon 3 in den letzten 4 Prüfungen · S24 T1 A2a/b (REST-Konzept 2 P, CRUD-Tabelle 6 P), S26 T1 A2ba/bc (REST-Konzept 3 P, zwei weitere HTTP-Methoden 6 P)
| Prinzip | Bedeutung | Beispiel (Bibliotheks-API) |
|---|---|---|
| Ressourcen mit eindeutiger URI | Alles, worauf man zugreift (Medium, Leser, Ausleihe), ist eine Ressource mit eigener Adresse. | /medien/M-30815/leser/4711/ausleihen |
| einheitliche Schnittstelle | Ressourcen werden nur über die Standardmethoden von HTTP bearbeitet; Ergebnisse werden mit Standard-Statuscodes gemeldet. | GET liest, DELETE löscht – bei jeder Ressource gleich |
| Repräsentationen | Übertragen wird eine Darstellung der Ressource (meist JSON, auch XML), nicht die Ressource selbst. Der Client kann das Format wählen. | Accept: application/json |
| Zustandslosigkeit | Jeder Request enthält alle nötigen Informationen (auch die Authentifizierung). Der Server speichert zwischen zwei Requests keinen Sitzungszustand des Clients. | Token in jedem Request |
| Client-Server | Oberfläche (Client) und Datenhaltung/Logik (Server) sind getrennt und unabhängig weiterentwickelbar. | App, Website und Partner nutzen dieselbe API |
| Cachefähigkeit | Antworten geben an, ob und wie lange sie zwischengespeichert werden dürfen. | Cache-Control: max-age=3600 |
| Schichtensystem | Zwischen Client und Server dürfen Proxys, Load-Balancer oder Gateways liegen, ohne dass der Client es merkt. | API-Gateway vor mehreren Servern |
Selten gefragt: HATEOAS – Antworten enthalten Links auf mögliche Folgeaktionen, z. B. zur Verlängerung einer Ausleihe.
CRUD steht für die vier Grundoperationen auf Daten: Create, Read, Update, Delete. Bei REST übernimmt die HTTP-Methode die Rolle des Verbs, die URI benennt nur die Ressource.
| CRUD | HTTP-Methode | Beispiel (Bibliothek) | typische Antwort |
|---|---|---|---|
| Create – anlegen | POST (Server vergibt die ID) PUT, wenn der Client die URI/ID festlegt | POST /leser/4711/vormerkungen | 201 Created + Header Location |
| Read – lesen | GET | GET /medien?titel=Momo | 200 OK + Daten |
| Update – ändern | PUT (vollständig ersetzen) PATCH (einzelne Felder ändern) | PATCH /leser/4711 | 200 OK oder 204 No Content |
| Delete – löschen | DELETE | DELETE /leser/4711/vormerkungen/912 | 204 No Content (oder 200) |
Weitere Methoden: HEAD (wie GET, aber nur die Header – z. B. um Größe oder Änderungsdatum zu prüfen) und OPTIONS (welche Methoden sind für eine Ressource erlaubt?).
Warum das wichtig ist: Bei schlechter Verbindung weiß ein Client oft nicht, ob seine Anfrage angekommen ist. Idempotente Anfragen darf er (oder ein Proxy) gefahrlos wiederholen – bei nicht idempotenten Anfragen kann eine Wiederholung Schaden anrichten.
Die Ressource /leser/4711 sieht so aus: {"leserNr": 4711, "name": "Tom Berger", "email": "tom@mail.example", "newsletter": false}. Nur die E-Mail-Adresse soll sich ändern:
PUT /v2/leser/4711
Content-Type: application/json
{"leserNr": 4711, "name": "Tom Berger",
"email": "t.berger@mail.example",
"newsletter": false}
PATCH /v2/leser/4711
Content-Type: application/json
{"email": "t.berger@mail.example"}
PUT überträgt die vollständige neue Repräsentation und ersetzt die alte. Schickt man bei PUT nur ein Feld, wären die übrigen danach leer bzw. auf Standardwerte gesetzt. PATCH überträgt nur die Änderung.
/medien, nicht /getMedien. Die Aktion steckt in der HTTP-Methode./leser/{leserNr}/ausleihen/{ausleihId}./medien/M-30815). Query-Parameter filtern, sortieren oder teilen eine Ergebnisliste in Seiten auf (/medien?typ=dvd&sort=titel&seite=2) – sie sind meist optional..json); das Format regeln Accept und Content-Type./v1/…, /v2/…), seltener über einen Header: Bei inkompatiblen Änderungen (Feld umbenannt, Struktur geändert) wird eine neue Version veröffentlicht, die alte bleibt eine Zeit lang parallel erreichbar. So funktionieren bereits ausgelieferte Clients (z. B. nicht aktualisierte Apps) weiter.| Anforderung (Bibliothek) | schlecht | besser |
|---|---|---|
| alle DVDs anzeigen | GET /getAllDvds | GET /medien?typ=dvd |
| Leser 4711 löschen | GET /leser/delete?id=4711 | DELETE /leser/4711 |
| Vormerkung anlegen | POST /neueVormerkung | POST /leser/4711/vormerkungen |
| E-Mail-Adresse eines Lesers ändern | POST /leser/4711/update | PATCH /leser/4711 |
/loescheLeser) oder Daten ändernde Aktionen per GET – GET muss sicher bleiben (Suchmaschinen, Caches und Vorschau-Funktionen rufen GET-Links einfach auf).POST /leser), PUT ersetzt eine bestimmte Ressource (PUT /leser/4711)./leser?id=4711) – funktioniert, widerspricht aber der Idee „eine Ressource = eine URI“.In S24 T1 A2e (11 P) sollte der Ablauf App → WebService → Datenbank als Sequenzdiagramm mit alt-Fragment gezeichnet werden (Notation siehe Block 03 UML). So sieht das für eine einfache Leseanfrage aus:
| REST | SOAP | |
|---|---|---|
| Art | Architekturstil | Protokoll (W3C-Standard) |
| Datenformat | beliebig, meist JSON | nur XML (SOAP-Envelope mit Header und Body) |
| Beschreibung | optional, z. B. OpenAPI | verbindlich per WSDL |
| Aufruf | HTTP-Methoden auf Ressourcen-URIs | meist ein Endpunkt, Operation steht im XML (fast immer POST) |
| Eigenschaften | leichtgewichtig, cachebar, zustandslos | umfangreich, mit Zusatzstandards (WS-Security, Transaktionen) |
| Einsatz | Web, Apps, öffentliche APIs | Banken, Behörden, ältere Unternehmenssysteme |
Vorkommen: REST/HTTP zusammen 4/9 · W21 T1 A3c (Ursache für HTTP 404, 2 P), S24 T1 A2c/d (Bestandteile eines Requests 3 P, Statuscode-Klassen 3 P), W24 T2 A2a (HTTP-Antwort im Code bauen, 10 P), S26 T1 A2bb (Parameter einer URL beschreiben, 3 P)
HTTP (Hypertext Transfer Protocol) ist ein Protokoll der Anwendungsschicht nach dem Request-Response-Prinzip: Der Client sendet eine Anfrage, der Server beantwortet sie. HTTP ist zustandslos – jede Anfrage steht für sich (Sitzungen entstehen erst durch Cookies oder Tokens). Standardport 80; HTTPS ist HTTP über eine TLS-verschlüsselte Verbindung (Port 443) und heute der Normalfall. Bei HTTP/1.1 sind die Nachrichten reiner Text; HTTP/2 und HTTP/3 übertragen binär, Methoden, Header und Statuscodes bleiben aber gleich.
| Header | in | Bedeutung |
|---|---|---|
| Host | Request | Name des Zielservers (Pflicht bei HTTP/1.1) |
| Content-Type | beide | Format des Bodys: application/json, application/xml, text/plain, text/html, ggf. mit charset=utf-8 |
| Accept | Request | Format, das der Client als Antwort haben möchte |
| Authorization | Request | Zugangsdaten, z. B. Bearer <Token> oder Basic <Base64(name:passwort)> |
| X-API-Key | Request | API-Schlüssel (eigener Header, der Name ist je nach API verschieden) |
| Content-Length | beide | Länge des Bodys in Bytes |
| Location | Response | URI der neu angelegten Ressource (bei 201) oder Ziel einer Weiterleitung (bei 3xx) |
| Cache-Control | Response | ob und wie lange die Antwort zwischengespeichert werden darf |
| Set-Cookie / Cookie | Resp. / Req. | Cookie setzen bzw. mitsenden (z. B. Sitzungs-ID) |
| User-Agent | Request | Name und Version der Client-Software |
?; Parameter haben die Form name=wert und werden durch & getrennt. Die Reihenfolge ist egal.%20 (oder +), ä → %C3%A4, & im Wert → %26.titel=Momo: Suchbegriff; es werden nur Medien geliefert, deren Titel ‚Momo‘ enthält“ oder „seite=2: Bei seitenweiser Ausgabe (Paginierung) wird die zweite Seite der Treffer geliefert“.Ein API-Schlüssel (API key) ist eine eindeutige, geheime Zeichenfolge, mit der sich eine Anwendung (nicht eine Person) gegenüber einer API ausweist. Zweck: nur registrierte Clients erhalten Zugriff, Anfragen lassen sich einem Kunden zuordnen (Abrechnung, Statistik), und die Anzahl der Anfragen lässt sich begrenzen (Rate-Limiting, Überschreitung → 429 Too Many Requests). Übertragung immer über HTTPS, besser im Header als in der URL, und nie im öffentlich einsehbaren Quellcode ablegen. Ein API-Schlüssel ersetzt keine Benutzeranmeldung – dafür gibt es Tokens (z. B. OAuth 2.0).
| Klasse | Bedeutung |
|---|---|
| 1xx | Information – Anfrage erhalten, Verarbeitung läuft |
| 2xx | Erfolg – Anfrage erfolgreich verarbeitet |
| 3xx | Umleitung – der Client muss eine andere URL aufrufen bzw. seinen Cache verwenden |
| 4xx | Client-Fehler – die Anfrage ist fehlerhaft oder nicht erlaubt; unverändert wiederholt scheitert sie erneut |
| 5xx | Server-Fehler – die Anfrage war in Ordnung, der Server konnte sie aber nicht ausführen |
| Code | Name |
|---|---|
| 200 | OK |
| 201 | Created |
| 204 | No Content |
| 301 / 302 | Moved Permanently / Found |
| 304 | Not Modified |
| 400 / 401 | Bad Request / Unauthorized |
| 403 / 404 | Forbidden / Not Found |
| 405 / 409 | Method Not Allowed / Conflict |
| 415 / 429 | Unsupported Media Type / Too Many Requests |
| 500 / 503 | Internal Server Error / Service Unavailable |
| Code | wann (am Beispiel der Bibliotheks-API) |
|---|---|
| 200 | GET liefert das Medium; PUT/PATCH erfolgreich und die geänderte Ressource steht im Body |
| 201 | POST hat eine Vormerkung angelegt; der Header Location nennt ihre URI |
| 204 | erfolgreich, aber bewusst ohne Body, z. B. nach dem Löschen einer Vormerkung |
| 301 | Die Ressource liegt dauerhaft unter einer neuen URL (steht in Location); Clients sollen künftig die neue URL nutzen. 302/307: nur vorübergehend |
| 400 | Anfrage formal oder inhaltlich ungültig: kaputtes JSON, Pflichtfeld fehlt, Datum im falschen Format |
| 401 | nicht authentifiziert: Token bzw. API-Schlüssel fehlt, ist abgelaufen oder falsch – „Wer bist du?“ |
| 403 | authentifiziert, aber nicht berechtigt: Leser 4711 will die Ausleihen von Leser 4712 sehen – „Ich weiß, wer du bist, aber das darfst du nicht.“ |
| 404 | unter dieser URL gibt es keine Ressource: unbekannte Mediennummer, falscher Pfad |
| 405 | Methode für diese Ressource nicht erlaubt, z. B. DELETE /medien |
| 409 | Widerspruch zum aktuellen Zustand: Medium ist bereits vom selben Leser vorgemerkt |
| 500 | unerwarteter Fehler im Server (z. B. nicht abgefangene Exception) |
| 503 | Dienst vorübergehend nicht verfügbar (Wartung, Überlastung, Datenbank nicht erreichbar); oft mit Header Retry-After |
In UTF-8 belegen ASCII-Zeichen (A–Z, a–z, Ziffern, Leerzeichen, { } " : usw.) je 1 Byte, ä ö ü Ä Ö Ü ß je 2 Bytes, das Eurozeichen € 3 Bytes, Emojis 4 Bytes. Gezählt wird nur der Body, nicht die Header.
| Body | Zeichen | Bytes = Content-Length |
|---|---|---|
| Bücherei geöffnet | 17 | 19 (ü und ö je +1) |
| Gebühr: 2,50 € | 14 | 17 (ü +1, € +2) |
In W24 T2 A2a war eine Klasse HttpResponse vorgegeben und eine Methode zu schreiben, die eine vollständige Antwort mit Statuscode, Content-Type, Content-Length (in Bytes) und Body erzeugt. Das Muster an einem einfachen Beispiel – ein „Lebenszeichen“-Endpunkt der Bibliotheks-API, der immer mit einem kurzen Text antwortet (Methoden wie in der Klasse HttpResponse des Belegsatzes):
funktion createPingResponse() : HttpResponse
body : string := "Bücherei-API läuft"
antwort : HttpResponse := new HttpResponse()
antwort.setStatus(200)
antwort.setHeader("Content-Type", "text/plain; charset=utf-8")
antwort.setHeader("Content-Length", body.byteLength().toString()) // 20, nicht 18!
antwort.setBody(body)
rückgabe antwort
Ende funktion
HTTP/1.1 200 OK Content-Type: text/plain; charset=utf-8 Content-Length: 20 Bücherei-API läuft
Prüfreihenfolge in einem Endpunkt. Ein Endpunkt prüft der Reihe nach und kehrt beim ersten Problem sofort mit dem passenden Code zurück („frühes Return“):
createErrorResponse(nachricht, statusCode) : HttpResponse implementieren; Antwort mit übergebenem Statuscode, Content-Type: text/plain, Content-Length = Anzahl der Bytes des Bodys, Body = Nachricht. Vorgegeben waren Konstruktor HttpResponse(code), addHeader(name, value) und setBody(content) – Namen können also variieren, das Muster bleibt.Vorkommen: 1/9, aber in der vorletzten Prüfung: W25 T1 A2b (9 P: englischer Text – Hauptziel, Aspekte einer digitalen Rechnung) und A3 (Transportverschlüsselung 4 P, Konformität sicherstellen 3 P, Online-Prüfseite 6 P, XSD-Validierung reicht nicht 6 P). Wegen der neuen gesetzlichen Pflicht ein naheliegendes Thema für weitere Prüfungen.
Nach der EU-Richtlinie 2014/55/EU und § 14 UStG ist eine elektronische Rechnung (eRechnung, e-invoice) eine Rechnung, die in einem strukturierten elektronischen Format ausgestellt, übermittelt und empfangen wird und eine automatische und elektronische Verarbeitung ermöglicht. In Deutschland muss das Format der europäischen Norm EN 16931 entsprechen (oder mit ihr kompatibel sein).
Zwei Aspekte einer digitalen Rechnung: Der visuelle Aspekt erlaubt einem Menschen, den Inhalt zu sehen und zu lesen (z. B. als PDF). Der Datenaspekt erlaubt einem Computer, die enthaltenen Informationen strukturiert zu verarbeiten (z. B. als XML mit festgelegten Feldern für Rechnungsnummer, Beträge, Steuersätze). Eine PDF hat nur den visuellen Aspekt, eine XRechnung nur den Datenaspekt, ZUGFeRD beide.
Vorteile: keine manuelle Erfassung, dadurch weniger Fehler und schnellere Bearbeitung und Zahlung; geringere Kosten für Druck, Porto und Erfassung; einfache, durchsuchbare Archivierung; automatische Prüfung (Pflichtangaben, Rechenwerte); Grundlage für digitale Meldeverfahren der Steuerverwaltung. Herausforderungen: Software muss eRechnungen erzeugen, prüfen, anzeigen und revisionssicher im Originalformat archivieren; Abläufe und Stammdaten müssen angepasst werden.
| Zeitpunkt | Regelung |
|---|---|
| seit 27.11.2020 | B2G (an öffentliche Auftraggeber): Lieferanten des Bundes müssen eRechnungen senden; die Länder haben eigene, ähnliche Regelungen. |
| seit 01.01.2025 | B2B: Alle inländischen Unternehmen müssen eRechnungen empfangen können. |
| bis 31.12.2026 | Übergang beim Versand: Papierrechnungen und sonstige elektronische Formate sind noch erlaubt; eine PDF nur mit Zustimmung des Empfängers. |
| bis 31.12.2027 | Übergang nur noch für Unternehmen mit einem Gesamtumsatz im Vorjahr von höchstens 800.000 € (außerdem für vereinbarte EDI-Verfahren). |
| ab 01.01.2028 | Alle Unternehmen müssen im B2B-Bereich eRechnungen ausstellen. |
Ausnahmen: Kleinbetragsrechnungen bis 250 € (brutto) und Fahrausweise. Rechnungen an Privatkunden (B2C) sind nicht betroffen. eRechnungen müssen im Originalformat (also als XML) aufbewahrt werden (GoBD) – ein ausgedrucktes Bild reicht nicht.
Die EN 16931 legt ein semantisches Datenmodell der „Kernrechnung“ fest (welche Angaben es gibt und was sie bedeuten, z. B. BT-1 Rechnungsnummer) und lässt zwei XML-Syntaxen zu: UBL (Universal Business Language) und UN/CEFACT CII (Cross Industry Invoice). In Deutschland sind zwei Formate verbreitet:
| XRechnung | ZUGFeRD | PDF / Scan | |
|---|---|---|---|
| Art | reines XML (UBL oder CII); deutsche Ausprägung (CIUS) der EN 16931, gepflegt von der KoSIT | hybrid: PDF/A-3-Dokument mit eingebetteter XML-Datei (CII); baugleich mit dem französischen Factur-X | Bild bzw. Text ohne Datenstruktur |
| für Menschen | nur mit Viewer/Visualisierung lesbar | PDF direkt lesbar | lesbar |
| für Software | direkt verarbeitbar | XML-Teil direkt verarbeitbar | nur per Abtippen/Texterkennung |
| Einsatz | öffentliche Auftraggeber (B2G), zunehmend B2B; öffentliche Empfänger verlangen meist die Leitweg-ID | B2B, vor allem wenn der Empfänger die Rechnung auch ohne Spezialsoftware lesen soll | B2B nur in der Übergangszeit |
| eRechnung? | ja | ja, ab Profil EN 16931 (nicht die Profile MINIMUM und BASIC WL) | nein |
Bei ZUGFeRD ist der XML-Teil maßgeblich: Weichen PDF und XML voneinander ab, gelten die XML-Daten. Die Leitweg-ID ist eine Kennung des öffentlichen Rechnungsempfängers (z. B. einer bestimmten Behörde oder Einrichtung). Sie wird vom Auftraggeber mitgeteilt, steht in der XRechnung im Feld „Käuferreferenz“ (BT-10) und sorgt dafür, dass die Rechnung automatisch an die zuständige Stelle weitergeleitet wird.
So sieht der Anfang einer echten XRechnung im UBL-Format aus (Auszug, Beispiel einer Tischlerei an eine Behörde; cbc und cac sind Namensraum-Präfixe):
<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#…:xrechnung_3.0</cbc:CustomizationID>
<cbc:ID>TB-2026-0815</cbc:ID> <!-- Rechnungsnummer (BT-1) -->
<cbc:IssueDate>2026-10-02</cbc:IssueDate> <!-- Rechnungsdatum -->
<cbc:DueDate>2026-11-01</cbc:DueDate> <!-- Fälligkeit -->
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <!-- 380 = Handelsrechnung -->
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>04011000-1234512345-06</cbc:BuyerReference> <!-- Leitweg-ID -->
<!-- … Verkäufer, Käufer, Zahlungsangaben, Steuern … -->
<cac:LegalMonetaryTotal> <!-- Summen: Positionen, netto, brutto, Zahlbetrag -->
<cbc:LineExtensionAmount currencyID="EUR">1200.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">1200.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1428.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1428.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<!-- … Rechnungspositionen (cac:InvoiceLine) … -->
</ubl:Invoice>
Das Gesetz schreibt keinen bestimmten Weg vor. Üblich sind:
Eine eRechnung wird in zwei Stufen geprüft:
Beides erledigt der KoSIT-Validator, das offizielle Prüfwerkzeug: frei verfügbar (Open Source), lokal ausführbar und auch in automatisierte Tests einbindbar; er erstellt einen Prüfbericht. Bei der Entwicklung einer Rechnungssoftware sichern außerdem ab: die verbindlichen Anforderungen der Spezifikation konsequent umsetzen, erprobte Bibliotheken nutzen, automatisierte Tests mit den offiziellen Testrechnungen, Testläufe mit Empfängern bzw. deren Portalen (Interoperabilität) und die Validierung als festen Schritt vor jedem Versand.
In W25 kam die eRechnung als englischer Text. Gefragt wird nicht nach einer Übersetzung, sondern nach dem Inhalt in eigenen Worten auf Deutsch. Erst die Frage lesen, dann im Text die passende Stelle suchen (Schlüsselwörter wie main objective, aspects, from … until), dann in ganzen Sätzen antworten. Hilfreiche Vokabeln:
| Englisch | Deutsch | Englisch | Deutsch |
|---|---|---|---|
| invoice / to issue | Rechnung / ausstellen | recipient / consent | Empfänger / Zustimmung |
| structured format | strukturiertes Format | turnover / threshold | Umsatz / Grenzwert |
| transmission channel | Übertragungsweg | transition period | Übergangsfrist |
| to comply with | einhalten, entsprechen | to be exempt | ausgenommen sein |
| embedded | eingebettet | to prevail | Vorrang haben, maßgeblich sein |
| public authority | Behörde | routing ID | Leitweg-ID |
Für diesen Block legt die IHK keine Notationshilfen bei. Der Belegsatz enthält deshalb nur die Anlagen zur Ausgangssituation (Szenario, API-Dokumentation, Beispielnachrichten, Klassen, XML- und JSON-Daten, englischer Text). Keine Erklärungen.
Die Aufgaben dieses Blocks beziehen sich auf die folgende Ausgangssituation:
Die FrischeKiste Nordheide GmbH mit Sitz in Heidmoor beliefert Haushalte, Firmen und Einrichtungen mit Obst- und Gemüsekisten aus der Region. Rund 2.400 Privatkunden haben ein Abonnement, dazu kommen etwa 60 Geschäftskunden, darunter Büros, Kantinen sowie die Kitas und Schulen der Stadt Heidmoor. Die Ware stammt von 28 Erzeugerbetrieben. Ausgeliefert wird dienstags bis freitags mit sechs Transportern. Der Umsatz betrug 2025 rund 4,3 Mio. €, für 2026 werden rund 4,6 Mio. € erwartet.
Die bisherige Lösung aus Webshop, Tabellenkalkulation und E-Mail soll durch die Plattform „KistenPortal“ ersetzt werden:
Sie sind Auszubildende/r zum Fachinformatiker/zur Fachinformatikerin Anwendungsentwicklung bei der Kranich Softwarehaus GmbH in Lüneburg, die das KistenPortal entwickelt.
Basis-URL: https://api.frischekiste.example/v1
Content-Type: application/json.X-API-Key mit dem Schlüssel der aufrufenden Anwendung enthalten (Kunden-App, Webshop, Fahrer-App oder Partnerzugang). Partnerzugänge der Erzeugerbetriebe dürfen Kisten nur lesen.JJJJ-MM-TT.{"status": <Statuscode>, "fehler": "<Meldung>"} beantwortet.| Ressource | Schlüssel | Beschreibung |
|---|---|---|
| kisten | kisteId | Kistenarten (Obst-, Gemüse-, Mischkisten), siehe Anlage 7 |
| kunden | kundenNr | Kundenkonten, siehe Anlage 8 |
| abos | aboId | Abonnements eines Kunden (Unterressource von kunden) |
| lieferadressen | adrId | Lieferadressen eines Kunden (Unterressource von kunden) |
| bestellungen | bestellNr | Bestellungen und Lieferungen; Attribut datum |
| reklamationen | reklaId | Reklamationen zu einer Bestellung (Unterressource von bestellungen) |
| touren | tourNr | Liefertouren eines Tages |
| Methode | Endpunkt | Beschreibung | bei Erfolg |
|---|---|---|---|
| GET | /kisten | alle Kistenarten | 200 OK |
| GET | /kisten/{kisteId} | eine Kistenart | 200 OK |
| GET | /kunden/{kundenNr}/abos | alle Abos eines Kunden | 200 OK |
| GET | /kunden/{kundenNr}/abos/{aboId} | ein Abo | 200 OK |
| POST | /kunden/{kundenNr}/abos | neues Abo anlegen | 201 Created, Header Location |
| GET | /touren/{datum}/{tourNr}/stopps | Stopps einer Tour (Fahrer-App) | 200 OK |
Repräsentation eines Abos (Antwort auf GET /v1/kunden/10427/abos/5531):
{
"aboId": 5531,
"kundenNr": 10427,
"kisteId": "K-OBST-M",
"rhythmus": "woechentlich",
"liefertag": "DI",
"lieferadresseId": 1,
"status": "aktiv",
"pausiertBis": null
}
Erlaubte Werte: rhythmus: woechentlich | 14-taegig · liefertag: DI | MI | DO | FR · status: aktiv | pausiert | gekuendigt · pausiertBis: Datum oder null
Request
POST /v1/kunden/10427/abos HTTP/1.1
Host: api.frischekiste.example
Content-Type: application/json
Accept: application/json
X-API-Key: app-7Fq2-Lx91
Content-Length: 88
{"kisteId": "K-GEM-L", "rhythmus": "14-taegig", "liefertag": "FR", "lieferadresseId": 2}
Response
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: /v1/kunden/10427/abos/5547
Content-Length: 162
{"aboId": 5547, "kundenNr": 10427, "kisteId": "K-GEM-L", "rhythmus": "14-taegig", "liefertag": "FR", "lieferadresseId": 2, "status": "aktiv", "pausiertBis": null}
Hinweise:
getOrt(), getAnzahlKisten(); bei boolean: isBio(), isZugestellt()).getPfadParameter, getHeader und getQueryParameter liefern null, wenn der Parameter bzw. Header nicht vorhanden ist. findeKiste liefert null, wenn es keine Kiste mit dieser ID gibt.Kiste.toJson() liefert die JSON-Repräsentation der Kiste, z. B. {"kisteId": "K-GEM-L", "bezeichnung": "Gemüsekiste groß", …}.string): text.length() liefert die Anzahl der Zeichen, text.byteLength() die Anzahl der Bytes in UTF-8-Kodierung. Zeichenketten werden mit + verkettet; Zahlen werden dabei automatisch in Text umgewandelt. zahl.toString() wandelt eine Zahl in eine Zeichenkette um. Ein Anführungszeichen innerhalb einer Zeichenkette wird als \" geschrieben.XML-Dokument wochenangebot_kw46.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE wochenangebot SYSTEM "wochenangebot.dtd"> 3 <wochenangebot kw="46"> 4 <erzeuger erzeugerId="E07"> 5 <name>Hof Brammer</name> 6 <ort>Wiesede</ort> 7 <biozertifikat>DE-ÖKO-006</biozertifikat> 8 </erzeuger> 9 <artikel artNr="A-101" einheit="kg"> 10 <bezeichnung>Möhren, lose</bezeichnung> 11 <menge>120</menge> 12 <preis>1.40</preis> 13 </artikel> 14 <artikel artNr="A-102" einheit="stueck"> 15 <bezeichnung>Kürbis Hokkaido</Bezeichnung> 16 <menge>40</menge> 17 <preis>2.10</preis> 18 <hinweis>nur bis KW 48 lieferbar</hinweis> 19 </artikel> 20 <artikel artNr="A-103" einheit="bund"> 21 <bezeichnung>Lauchzwiebeln</bezeichnung> 22 <preis>0.90</preis> 23 <menge>60</menge> 24 </artikel> 25 <artikel artNr="A-101" einheit="Kilo"> 26 <bezeichnung>Rote Bete</bezeichnung> 27 <menge>35<menge> 28 <preis>1.80</preis> 29 <lieferant>Hof Brammer</lieferant> 30 </artikel> 31 <artikel artNr=A-105> 32 <bezeichnung>Feldsalat</bezeichnung> 33 <menge>15</menge> 34 <preis>7.50</preis> 35 </artikel> 36 </wochenangebot>
Externe DTD wochenangebot.dtd
1 <!ELEMENT wochenangebot (erzeuger, artikel+)> 2 <!ATTLIST wochenangebot kw CDATA #REQUIRED 3 jahr CDATA #REQUIRED> 4 <!ELEMENT erzeuger (name, ort, biozertifikat?)> 5 <!ATTLIST erzeuger erzeugerId ID #REQUIRED> 6 <!ELEMENT name (#PCDATA)> 7 <!ELEMENT ort (#PCDATA)> 8 <!ELEMENT biozertifikat (#PCDATA)> 9 <!ELEMENT artikel (bezeichnung, menge, preis, hinweis*)> 10 <!ATTLIST artikel artNr ID #REQUIRED 11 einheit (kg|stueck|bund) "kg"> 12 <!ELEMENT bezeichnung (#PCDATA)> 13 <!ELEMENT menge (#PCDATA)> 14 <!ELEMENT preis (#PCDATA)> 15 <!ELEMENT hinweis (#PCDATA)>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE lieferschein SYSTEM "lieferschein.dtd"> 3 <lieferschein nr="LS-2026-1187" datum="2026-11-10"> 4 <kunde kundenNr="20015"> 5 <name>Kita Sonnenblume</name> 6 <adresse>Am Mühlenbach 3, 21391 Heidmoor</adresse> 7 </kunde> 8 <position> 9 <kiste>K-OBST-M</kiste> 10 <anzahl>4</anzahl> 11 </position> 12 <position> 13 <kiste>K-GEM-L</kiste> 14 <anzahl>2</anzahl> 15 <bemerkung>ohne Sellerie</bemerkung> 16 <bemerkung>Kühlware zuerst ausladen</bemerkung> 17 </position> 18 <fahrer>T. Ohlsen</fahrer> 19 </lieferschein>
| kisteId | bezeichnung | groesse | preis | bio | gewichtKg | saisonEnde |
|---|---|---|---|---|---|---|
| K-OBST-M | Obstkiste mittel | M | 18.50 | ja | 4.5 | |
| K-GEM-L | Gemüsekiste groß | L | 27.90 | ja | 8.0 | 2027-03-31 |
| K-MIX-S | Mischkiste klein | S | 14.20 | nein | 3.0 |
| kisteId | artikel | menge | einheit |
|---|---|---|---|
| K-OBST-M | Äpfel Elstar | 1.5 | kg |
| K-OBST-M | Birnen Conference | 1 | kg |
| K-OBST-M | Bananen | 6 | Stück |
| K-GEM-L | Möhren | 2 | kg |
| K-GEM-L | Kürbis Hokkaido | 1 | Stück |
| … | … | … | … |
Eine leere Zelle bedeutet: kein Wert vorhanden.
| kundenNr | name | kundentyp | newsletter | |
|---|---|---|---|---|
| 10427 | Jana Petersen | privat | j.petersen@mail.example | ja |
| 20015 | Kita Sonnenblume | oeffentlich | verwaltung@kita-sonnenblume.example | nein |
| adrId | kundenNr | strasse | plz | ort | ablageort |
|---|---|---|---|---|---|
| 1 | 10427 | Lindenweg 4 | 21391 | Heidmoor | Garage |
| 2 | 10427 | Hafenstraße 18 | 21423 | Kleinmoor | |
| 3 | 20015 | Am Mühlenbach 3 | 21391 | Heidmoor | Küche, Hintereingang |
Eine leere Zelle bedeutet: kein Wert vorhanden.
| position | kundenNr | ort | anzahlKisten | zugestellt |
|---|---|---|---|---|
| 1 | 10427 | Heidmoor | 2 | true |
| 2 | 20015 | Heidmoor | 6 | false |
| 3 | 10533 | Wiesede | 1 | false |
| 4 | 10871 | Kleinmoor | 3 | true |
| 5 | 20022 | Wiesede | 4 | false |
Die Stopps liegen in einer Liste List<Stopp> in der Reihenfolge der Tabelle vor (Klasse Stopp siehe Anlage 4).
// JSON-Syntaxbeschreibung
// wert kann sein: "zeichenkette", zahl, true, false, null, objekt, array
{
"attributname": wert,
...,
"objektname": {
"attributname": wert,
...
},
"arrayname": [
wert,
...
]
}
E-invoicing in Germany: what businesses need to know
Since 1 January 2025, every business in Germany has to be able to receive electronic invoices from other businesses (B2B). Under the new rules, an e-invoice is an invoice that is issued, transmitted and received in a structured electronic format which complies with the European standard EN 16931 and allows the data to be processed automatically. A PDF file attached to an e-mail is therefore no longer regarded as an e-invoice but as an “other invoice”. Invoices to private consumers (B2C) are not affected by the new rules.
For issuing e-invoices, the law provides transition periods. Until 31 December 2026, businesses may still send paper invoices or invoices in other electronic formats such as PDF; sending a PDF, however, requires the consent of the recipient. During 2027, this option is only available to businesses whose total turnover in the previous year did not exceed EUR 800,000. From 1 January 2028, all businesses must issue e-invoices. Invoices for small amounts of up to EUR 250 and travel tickets are exempt.
Two formats are widely used. XRechnung is a purely XML-based format; it is required by many public authorities, which use a routing ID (“Leitweg-ID”) to forward each invoice to the responsible department. ZUGFeRD is a hybrid format: a PDF/A-3 document that contains the invoice data as an embedded XML file. People can read the PDF, while software processes the XML. If the two parts differ, the XML data prevail.
The law does not prescribe a specific transmission channel. E-invoices can be sent by e-mail, uploaded to a portal, exchanged via an API or delivered through the Peppol network. In any case, they must be stored in their original format.
Selbst verfasster Text auf Grundlage der Rechtslage 2026.
1 <?xml version="1.0" encoding="UTF-8"?> 2 <rechnung xmlns="urn:kranich:frischekiste:rechnung:1.0"> 3 <rechnungsnummer>RE-2026-04711</rechnungsnummer> 4 <rechnungsdatum>2026-11-30</rechnungsdatum> 5 <faelligAm>2026-11-16</faelligAm> 6 <leitwegId>03359012-4711-08</leitwegId> 7 <verkaeufer> 8 <name>FrischeKiste Nordheide GmbH</name> 9 <ustId>DE123456789</ustId> 10 </verkaeufer> 11 <kaeufer> 12 <name>Stadt Heidmoor, Kita Sonnenblume</name> 13 </kaeufer> 14 <position nr="1"> 15 <bezeichnung>Obstkiste mittel</bezeichnung> 16 <menge>8</menge> 17 <einzelpreis>18.50</einzelpreis> 18 <nettobetrag>148.00</nettobetrag> 19 <steuersatz>7</steuersatz> 20 </position> 21 <position nr="2"> 22 <bezeichnung>Gemüsekiste groß</bezeichnung> 23 <menge>4</menge> 24 <einzelpreis>27.90</einzelpreis> 25 <nettobetrag>101.60</nettobetrag> 26 <steuersatz>7</steuersatz> 27 </position> 28 <summen> 29 <nettogesamt>259.60</nettogesamt> 30 <umsatzsteuer>18.17</umsatzsteuer> 31 <bruttogesamt>278.77</bruttogesamt> 32 </summen> 33 </rechnung>
Das Dokument wurde erfolgreich gegen das zugehörige XML-Schema rechnung.xsd validiert (Datentypen: Datumsangaben xs:date, Mengen und Beträge xs:decimal). Beträge in Euro, steuersatz in Prozent; für Lebensmittel gilt der ermäßigte Steuersatz von 7 %.
Alle Aufgaben beziehen sich auf die Ausgangssituation in Anlage 1. Algorithmen sind in Pseudocode zu entwickeln; eine Programmiersprache (z. B. Java) ist ebenfalls zulässig. Für alle Attribute stehen Get-Methoden zur Verfügung (Anlage 4).
Die Fahrer-App meldet nach jeder Lieferung den Status an den Server. Ein Kollege zeigt Ihnen eine solche Statusmeldung:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <lieferung nr="88120"> 3 <status>zugestellt</status> 4 <zeit>2026-11-10T09:42:00</zeit> 5 <ablage hinweis="Garage"/> 6 </lieferung>
| Bestandteil | Bezeichnung |
|---|---|
| <?xml version="1.0" encoding="UTF-8"?> | |
das Element lieferung (Zeilen 2–6) | |
| nr="88120" | |
| <ablage hinweis="Garage"/> |
| Eigenschaft | Erläuterung | trifft auf die Statusmeldung zu? |
|---|---|---|
| wohlgeformt | ||
| gültig |
Angelehnt an: W22 Teil 1, Aufgabe 3cb
Für die Stammdaten der Erzeugerbetriebe und für die Lieferscheine werden Strukturbeschreibungen benötigt.
| Deklaration | Bedeutung |
|---|---|
| <!ELEMENT erzeuger (name, telefon?, email+, hof)> | |
| <!ELEMENT hof (adresse | koordinaten)> | |
| <!ATTLIST erzeuger id ID #REQUIRED status (aktiv|pausiert) "aktiv"> | |
| <xs:element name="zertifikat" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> |
lieferschein.dtd für den Lieferschein in Anlage 6. Es gelten folgende Regeln:
nr) und Datum (datum) sind Pflichtattribute des Lieferscheins, die Kundennummer (kundenNr) ist Pflichtattribut des Kunden.Angelehnt an: W22 Teil 1, Aufgabe 3c (DTD lesen)
Die Erzeugerbetriebe laden ihr Wochenangebot als XML-Datei im KistenPortal hoch. Bevor die Daten importiert werden, prüft das KistenPortal jede Datei gegen die externe DTD wochenangebot.dtd (Anlage 5).
| Zeile | Beschreibung | Eigenschaft |
|---|---|---|
| 29 | Das Element lieferant ist in der DTD nicht deklariert. | Gültigkeit |
<artikel artNr="A-110" einheit="kg"> <bezeichnung>Grünkohl</bezeichnung> <menge>ca. 80</menge> <preis>-1.90</preis> </artikel>Erläutern Sie, warum diese Werte die Prüfung gegen die DTD bestehen, und beschreiben Sie zwei Maßnahmen, mit denen solche Fehler vor dem Import erkannt werden können.
Angelehnt an: W22 Teil 1, Aufgabe 3c (Fehler anhand einer DTD finden) und W25 Teil 1, Aufgabe 3bc (Grenzen der Schema-Validierung)
1 { 2 'kisteId': "K-MIX-S", 3 "preis": 14,20, 4 "bio": False, 5 "inhalt": ["Äpfel", "Möhren", "Kartoffeln",] 6 }
| Zeile | Fehler | Korrektur |
|---|---|---|
Die Kistenarten sollen aus den bisherigen Tabellen (Anlage 7) in die dokumentenorientierte Datenbank übernommen und über die API an die App geliefert werden.
Kiste in ein JSON-Dokument mit einem Array kisten. Wählen Sie für jeden Wert einen passenden JSON-Datentyp. Nutzen Sie die Syntaxbeschreibung in Anlage 10.K-OBST-M das Array inhalt an, das mit den Einträgen der Tabelle Kisteninhalt in das Objekt aus a) eingebettet wird.Angelehnt an: W23 Teil 1, Aufgabe 3ca
Auch die Kundendaten werden in die dokumentenorientierte Datenbank übernommen. Außerdem soll die Fahrer-App die offenen Stopps einer Tour als JSON erhalten.
Kunde und Lieferadresse (Anlage 8) in ein JSON-Dokument mit den Arrays kunden und lieferadressen. Die Zuordnung einer Lieferadresse zu ihrem Kunden erfolgt wie bisher über die Kundennummer (Referenz).| Datenbestand | Embedding oder Referenz? | Begründung |
|---|---|---|
| (1) die Bestellungen eines Kunden: Ein Abo-Kunde sammelt über die Jahre mehrere Hundert Bestellungen; beim Öffnen des Kundenkontos zeigt die App nur Name und Lieferadressen. | ||
| (2) die Positionen einer Bestellung (Kiste, Anzahl, Preis zum Bestellzeitpunkt): Eine Bestellung hat ein bis fünf Positionen, sie werden immer mit der Bestellung angezeigt und ändern sich danach nicht mehr. |
offeneStoppsAlsJson(stopps : List<Stopp>) : string. Sie liefert alle noch nicht zugestellten Stopps als JSON-Array in der Reihenfolge der Liste. Jedes Objekt enthält die Schlüssel position, kundenNr, ort und kisten (Anzahl der Kisten). Gibt es keine offenen Stopps, wird [] zurückgegeben. Zeilenumbrüche und Einrückungen sind nicht erforderlich. Klasse Stopp und Hinweise zu Zeichenketten: Anlage 4.[{"position": 2, "kundenNr": 20015, "ort": "Heidmoor", "kisten": 6}, {"position": 3, "kundenNr": 10533, "ort": "Wiesede", "kisten": 1}, {"position": 5, "kundenNr": 20022, "ort": "Wiesede", "kisten": 4}]
Angelehnt an: W23 Teil 1, Aufgabe 3c (Tabellen in JSON, Embedding) und W24 Teil 1, Aufgabe 2c (Skript mit JSON-Ausgabe)
Die KistenPortal-API (Anlage 2) bildet die vier Grundoperationen auf Daten (CRUD) auf HTTP-Methoden ab.
| Operation | Beispiel im KistenPortal | HTTP-Methode |
|---|---|---|
| C – Create | ||
| R – Read | ||
| U – Update | ||
| D – Delete |
Angelehnt an: S24 Teil 1, Aufgabe 2b
Für die nächste Version der Kunden-App werden weitere Endpunkte benötigt. Halten Sie sich an die Konventionen der API-Dokumentation (Anlage 2).
| Nr. | Anforderung | Methode | Endpunkt |
|---|---|---|---|
| 1 | alle Bio-Kisten der Größe L anzeigen | ||
| 2 | das Abo 5531 der Kundin 10427 bis zum 24.11.2026 pausieren (nur Status und Datum ändern) | ||
| 3 | die Lieferadresse 2 der Kundin 10427 löschen | ||
| 4 | eine Reklamation zur Bestellung 88120 erfassen | ||
| 5 | die Lieferadresse 1 der Kundin 10427 vollständig durch neue Daten ersetzen | ||
| 6 | alle Bestellungen der Kundin 10427 aus dem November 2026 anzeigen |
/v1. Erläutern Sie den Zweck dieser Angabe.Die Geschäftsführung der FrischeKiste möchte die API künftig auch weiteren Partnern anbieten und lässt sich das Konzept erklären. Gleichzeitig melden Testkunden Auffälligkeiten in der App.
| Request | sicher | idempotent | Begründung |
|---|---|---|---|
| GET /v1/kisten?bio=true | |||
| POST /v1/kunden/10427/abos (Body wie in Anlage 3) | |||
| PUT /v1/kunden/10427/abos/5531 (vollständige Repräsentation) | |||
| PATCH /v1/kunden/10427/abos/5531 {"status": "pausiert", "pausiertBis": "2026-11-24"} | |||
| DELETE /v1/kunden/10427/lieferadressen/2 |
PUT und mit PATCH an (Request-Zeile und Body; Header dürfen entfallen).Angelehnt an: S24 Teil 1, Aufgabe 2a/2b und S26 Teil 1, Aufgabe 2ba/2bc
| Code | Bedeutung |
|---|---|
| 2xx | |
| 4xx | |
| 5xx |
Angelehnt an: S24 Teil 1, Aufgabe 2d und W21 Teil 1, Aufgabe 3c
| Bestandteil | Bedeutung |
|---|---|
| POST | HTTP-Methode: legt eine neue Ressource an – hier ein neues Abo in der Sammlung der Abos der Kundin |
| /v1/kunden/10427/abos | |
| Content-Type: application/json Accept: application/json | |
| X-API-Key: app-7Fq2-Lx91 | |
| {"kisteId": "K-GEM-L", "rhythmus": …} |
GET https://api.geodienst.example/v2/route?start=53.3297,9.8722&ziel=53.2464,10.4115&profil=transporter&apikey=GD-55K2-ZZ81
| Parameter | Beschreibung |
|---|---|
| /v2/route | die angefragte Ressource (eine Route) in Version 2 der API |
| start=53.3297,9.8722 ziel=53.2464,10.4115 | |
| profil=transporter | |
| apikey=GD-55K2-ZZ81 |
| Situation | Code | Begründung |
|---|---|---|
(1) Die App sendet POST /v1/kunden/10427/abos; im JSON-Body fehlt das Pflichtfeld kisteId. | ||
(2) Ein Erzeugerbetrieb sendet mit seinem gültigen Partnerschlüssel DELETE /v1/kisten/K-MIX-S. | ||
| (3) Die Kundin löscht ihre Lieferadresse 2 erfolgreich; die Antwort enthält bewusst keinen Body. | ||
(4) Eine veraltete App ruft /v0/kisten auf; diese Adresse wurde dauerhaft durch /v1/kisten ersetzt. |
Angelehnt an: S24 Teil 1, Aufgabe 2c und S26 Teil 1, Aufgabe 2bb
Sie implementieren in der Klasse KistenController (Anlage 4) den Endpunkt GET /v1/kisten/{kisteId}. Der Pfadparameter heißt kisteId.
createErrorResponse(statusCode : integer, meldung : string) : HttpResponse. Die erzeugte Antwort enthält
Content-Type mit dem Wert application/json; charset=utf-8,Content-Length mit der Anzahl der Bytes des Bodys,{"status": <statusCode>, "fehler": "<meldung>"} – genau in dieser Schreibweise, also mit je einem Leerzeichen nach Doppelpunkt und Komma.HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 57
{"status": 404, "fehler": "Kiste K-XXL-Z nicht gefunden"}
Content-Length mit body.length(). Erläutern Sie, warum das zu falschen Werten führen kann. Geben Sie für die Fehlerantwort mit dem Statuscode 503 und der Meldung „Katalog vorübergehend nicht verfügbar“ die Anzahl der Zeichen des Bodys und den korrekten Wert von Content-Length an.handleGetKiste(request : HttpRequest) : HttpResponse. Sie prüft in dieser Reihenfolge:
X-API-Key oder ist der Schlüssel ungültig: Statuscode 401, Meldung „API-Schlüssel fehlt oder ist ungültig“.kisteId aus dem Pfad: Statuscode 404, Meldung „Kiste <kisteId> nicht gefunden“.Content-Type und Content-Length wie in a).Angelehnt an: W24 Teil 2, Aufgabe 2a (HTTP-Antwort mit Statuscode, Content-Type und Content-Length bauen)
| Rechnung | eRechnung? | Begründung |
|---|---|---|
| (1) in der Textverarbeitung geschrieben, als PDF per E-Mail an eine Kantine geschickt | ||
| (2) XRechnung im UBL-Format, im Rechnungsportal der Stadt Heidmoor hochgeladen | ||
| (3) Papierrechnung, eingescannt und als JPG-Bild per E-Mail verschickt | ||
| (4) ZUGFeRD-Rechnung im Profil EN 16931, per E-Mail an ein Büro geschickt |
Angelehnt an: W25 Teil 1, Aufgabe 2ba
Die Geschäftsführung der FrischeKiste möchte wissen, was die eRechnungspflicht für das Unternehmen bedeutet. Sie haben den englischen Text in Anlage 11 gefunden. Beantworten Sie die Fragen auf Deutsch.
Angelehnt an: W25 Teil 1, Aufgabe 2b (englischer Fachtext zur eRechnung)
Die Kranich Softwarehaus GmbH entwickelt das Modul, das aus den Bestellungen eRechnungen erzeugt. Die Stadt Heidmoor verlangt für ihre Kitas und Schulen XRechnungen mit Leitweg-ID. Die Rechnungen an Geschäftskunden sollen per E-Mail versendet werden.
www.erechnung-check.example prüfen lassen. Dort lädt man eine Rechnung hoch und erhält ein Prüfergebnis. Erläutern Sie zwei Punkte, die bei der Nutzung zu beachten sind.Angelehnt an: W25 Teil 1, Aufgabe 3a und 3b
Diese echten Prüfungsaufgaben passen zu diesem Block (Dateien im Ordner Prüfungsvorbereitung). Lösungen gibt es nur für 2023 Sommer, 2023 Winter, 2024 Sommer und 2025 Winter (dort vom u-form-Verlag).
| Prüfung | Aufgabe | Thema | Datei · Lösung |
|---|---|---|---|
| Winter 2021 | T1 A3c (2 P) | Ursache für HTTP-Fehler 404 | 2021/winter/AE 2021 Winter Teil 1.pdf · keine Lösung |
| Winter 2022 | T1 A3c (13 P) | XML: Zweck der DTD, wohlgeformt/gültig, Fehler anhand der DTD finden | 2022/winter/AE 2022 Winter Teil 1.pdf · keine Lösung |
| Sommer 2023 | T1 A4cb (13 P) | Relationenmodell in 3NF inkl. JSON-Sensordaten | 2023/sommer/AE Sommer 2023 Teil 1.pdf · Lösung: AE Sommer 2023 Teil 1+2 Lösungen.pdf |
| Winter 2023 | T1 A3c (14 P) | Tabellen in JSON überführen, Verkaufsstellen als Array einbetten | 2023/winter/AE Winter 2023 Teil 1.pdf · Lösung: AE Winter 2023 Teil 1 Lösungen.pdf |
| Sommer 2024 | T1 A2 (25 P) | REST-Konzept, CRUD/HTTP-Methoden, Request-Bestandteile, Statuscodes, Sequenzdiagramm App/WebService/DB | 2024/sommer/AE Sommer 2024 Teil 1+2+3.pdf · Lösung: AE Sommer 2024 Teil 1 Lösungen.pdf |
| Winter 2024 | T1 A2c (8 P) | Skript: Subnetz durchlaufen, Ergebnis als JSON-Array | 2024/winter/AE Winter 2024 Teil 1.pdf · keine Lösung |
| Winter 2024 | T2 A2a (10 P) | HttpResponse mit Statuscode, Content-Type und Content-Length bauen | 2024/winter/AE Winter 2024 Teil 2.pdf · keine Lösung |
| Winter 2025 | T1 A2b (9 P) | eRechnung: englischer Text, Hauptziel, Aspekte einer digitalen Rechnung | 2025/winter/AE Winter 2025 Teil 1.pdf · Lösung: AE Winter 2025 Lösungserleuterungen.pdf (u-form) |
| Winter 2025 | T1 A3a, A3b (19 P) | Transportverschlüsselung, Konformität, Online-Prüfseite, XSD-Validierung reicht nicht | wie oben |
| Sommer 2026 | T1 A2b (12 P) | REST-Konzept, Parameter einer GET-URL, weitere HTTP-Methoden | 2026/sommer/AE Sommer 2026 Teil 1.pdf · keine Lösung |