Plattform-Architektur¶
Die ZEDAL-Plattform exponiert ihre Funktionalität als Familie von gRPC-Services. Integratoren erreichen sie auf drei Wegen: SDK, REST/JSON und gRPC direkt. Alle drei führen auf dieselbe Funktionalität zusammen, weil die .proto-Definitionen die einzige Wahrheitsquelle sind, aus der sich SDK, REST-Fassade und OpenAPI-Dokument ableiten.
Überblick¶
flowchart TB
subgraph integ["Integrator-Seite"]
APP["Anwendung<br/>Backend / Mobile / Web"]
end
subgraph edge["ZEDAL-Edge"]
SDK[".NET SDK<br/>Zedal.Sdk"]
REST["REST / JSON + gRPC-Web<br/>openapi.*.zedal.de"]
GRPC[("gRPC-Endpunkt<br/>api.*.zedal.de")]
end
subgraph backend["Backend-Services"]
CORE["Core<br/>Auth, Dokumente, Akten"]
BXA["BxA-Dokumente<br/>Company / Authority"]
DiWaSS["DiWaSS-Anbindung<br/>Retrieval, Attachment,<br/>Operator, Authority"]
SIGNER["Signer<br/>VerifyApi"]
DISC["DiscoveryApi"]
TRANS["TransformApi"]
end
subgraph ext["Externe Systeme"]
EU["EU DiWaSS<br/>Zentralsystem"]
end
APP --> SDK
APP --> REST
APP --> GRPC
SDK --> GRPC
REST --> GRPC
GRPC --> CORE
GRPC --> BXA
GRPC --> SIGNER
GRPC --> DiWaSS
GRPC --> DISC
GRPC --> TRANS
DiWaSS -.->|serverseitig vermittelt| EU
Drei Zugriffswege¶
Welcher Weg passt, hängt von Sprache, Integrationsstil und davon ab, ob du Streaming brauchst.
1. Offizielles SDK¶
Wann: wenn deine Anwendung in einer Sprache mit verfügbarem SDK gebaut ist.
Aktuell: .NET / C# — NuGet-Paket Zedal.Sdk, versioniert nach Semantic Versioning.
Das SDK kapselt gRPC, übernimmt Authentifizierung samt Token-Erneuerung und bietet für die DiWaSS-Dokumente eigene Document-Handler statt roher Request-Messages. Empfehlung für die meisten Integrationen.
Über die reine Protokoll-Kapselung hinaus gibt es Bausteine, die es auf dem gRPC- oder REST-Pfad nicht gibt und die du sonst selbst bauen müsstest:
| Baustein | Was er leistet |
|---|---|
Document-Handler (client.DocumentHandler) |
Notifizierung, Movement, Annex VII und die Behördensicht als Objekte mit Stage-Methoden und Followup-Intents |
Inbox-Importer (CreateInboxImporter()) |
Übernahme eingehender Dokumentversionen in den lokalen Bestand — siehe Aufrufe und Synchronisation |
| Token-Erneuerung | Der mitgelieferte DefaultTokenRefresher erneuert das Access-Token, sobald weniger als 5 Minuten Restlaufzeit bleiben. Er prüft nur die Ablaufzeit — entzogene oder gesperrte Zugänge behandelt er nicht; dafür brauchst du eine eigene IJwtTokenRefresh-Implementierung |
client.MyAccount |
Die eigenen DiWaSS-Operator-IDs und BMU-ZKS-Nummern des angemeldeten Nutzers |
2. REST / JSON¶
Wann: wenn du in einer Sprache ohne offizielles SDK arbeitest oder REST-Tooling bevorzugst. Status: produktiv. Details, Aufrufform und Codegenerierung: API-Referenz → REST.
Die REST-Routen und das OpenAPI-Dokument werden zur Laufzeit aus den gRPC-Definitionen abgeleitet. Daraus folgt:
- Kein Codegen-Schritt, kein Versionsversatz. Das OpenAPI-Dokument beschreibt exakt das, was der laufende Service kann. Deshalb ist die Referenz immer aktuell.
- Die Pfade sind RPC-förmig, nicht ressourcenorientiert:
<VERB> /<service.FullName>/<Methode>. - Das Verb kommt aus der
google.api.http-Annotation. Es ist nicht immer POST; auch GET, PATCH, DELETE und PUT kommen vor. - Eine Methode ohne HTTP-Annotation hat keine REST-Route. Es gibt gRPC-Methoden, die über REST nicht erreichbar sind — siehe die Spalte „REST” in der Tabelle unten.
- Die Referenz-Oberfläche ist Scalar, das Dokument ist OpenAPI 3.0.3.
REST/JSON ist unary — kein Server-Streaming
Eine Anfrage, eine Antwort. Server-Streaming steht über REST nicht zur Verfügung, auch nicht als Server-Sent Events. Wer Streaming braucht, nimmt natives gRPC oder gRPC-Web über denselben openapi.*-Host; dort werden Streaming-Antworten inkrementell ausgeliefert.
3. gRPC direkt¶
Wann: wenn du Streaming brauchst, geringe Latenz willst oder in deiner Sprache aus den Protos selbst generieren möchtest.
Der native gRPC-Endpunkt liegt auf dem api.*-Host und bietet die vollständige Oberfläche — einschließlich der Methoden ohne REST-Route. Siehe API-Referenz → gRPC.
Umgebungen¶
Die beiden Hosts pro Umgebung sind getrennt: natives gRPC auf api.*, REST/JSON und gRPC-Web auf openapi.*.
| Umgebung | nativ gRPC | REST/JSON + gRPC-Web |
|---|---|---|
| Production | api.live.zedal.de |
openapi.live.zedal.de |
| Preview | api.preview.zedal.de |
openapi.preview.zedal.de |
| Test | api.test.zedal.de |
openapi.test.zedal.de |
Provider-IDs sind umgebungsspezifisch
Eine Provider-ID aus der Produktion gilt nicht auf Test und umgekehrt. Auf dem REST-Pfad ist der Header provider_id bei jedem Aufruf Pflicht — auch beim Login. Eine falsche oder fehlende ID gibt dieselbe, irreführende 501-Antwort. Details in REST / JSON und Erste Schritte.
Services¶
Hinter dem gRPC-Endpunkt liegen mehrere thematische Services. Das SDK bündelt sie unter der IZedalClient-Fassade; über REST und gRPC sprichst du sie unter ihrem vollqualifizierten Namen an.
Die Spalte REST nennt, wie viele Methoden des Service über REST/JSON erreichbar sind. Der Zähler stammt aus dem OpenAPI-Dokument des laufenden Systems, der Nenner aus den Proto-Definitionen.
| SDK-Pfad | gRPC-Service | REST | Zuständigkeit |
|---|---|---|---|
CoreApi.Auth |
core.v1.api.AuthApi |
8 / 8 | Refresh-/Access-Token, Sessions, Passwortwechsel |
CoreApi.Documents |
core.v1.api.DocumentApi |
20 / 32 | Dokumente und Parameter lesen, Inbox, Import aus der Inbox, Versand und Quittierung |
CoreApi.File |
core.v1.api.FileApi |
13 / 23 | Akten und Einreichungen im Nachweis-Bereich |
CoreApi.Templates |
core.v1.api.DocumentTemplateApi |
4 / 6 | Muster für Versandpapiere und Akten |
CoreApi.MasterData |
core.v1.api.MasterdataApi |
1 / 2 | Adressstammdaten |
CoreApi.Common |
core.v1.api.CommonApi |
2 / 3 | Globale Parameter |
CoreApi.Query |
core.preview.api.PreviewApi |
2 / 8 | Übersichtslisten über Dokumente, Akten und Muster. Experimentell — Namen und Zuschnitt können sich ändern |
| — | core.v1.api.QueryApi |
3 / 5 | Übersichtslisten über Transportdokumente, Eingang, Akten-Dokumente, Akten und Muster. Ohne REST-Route: ListFileAreaDocuments, ListFiles |
BxaApi.CompanyDocumentApi |
bxa.diwass.v1.api.CompanyDocumentApi |
23 / 23 | Unternehmensseite der DiWaSS-Dokumente: Notifizierung, Movement, Annex VII anlegen und Stages setzen |
BxaApi.AuthorityDocumentApi |
bxa.diwass.v1.api.AuthorityDocumentApi |
9 / 9 | Behördenseite: Entscheidung, Nachforderung, Signale, Rücknahme |
BxaApi.BmuDocumentApi |
bxa.bmu.v1.api.BmuDocumentApi |
6 / 6 | BMU-Begleit- und Übernahmescheine: anlegen, Layer anhängen, Felder setzen, Signaturstellen; siehe BMU-Anleitung |
DiwassApi.RetrievalApi |
diwass.v1.api.RetrievalApi |
4 / 4 | Ereignisliste und Abgleich — siehe Aufrufe und Synchronisation |
DiwassApi.AttachmentApi |
diwass.v1.api.AttachmentApi |
2 / 2 | Anhänge einreichen und abrufen |
DiwassApi.OperatorApi |
diwass.v1.api.OperatorApi |
2 / 2 | Operator-Verzeichnis: Suche und Einzelabruf |
DiwassApi.AuthorityDirectoryApi |
diwass.v1.api.AuthorityApi |
4 / 4 | Behördenverzeichnis: Suche nach Tätigkeit, Einzelabruf, Änderungsstand |
DiwassApi.SoapProxyApi |
— | keine | Durchreichen eines rohen SOAP-Bodys an DiWaSS |
DiscoveryApi |
provider_discovery.v1.api.DiscoveryApi |
1 / 1 | Provider-Verzeichnis. ListProvider ist die einzige Operation ohne Token und ohne provider_id — damit Schritt 0 jeder Integration |
TransformApi |
— | keine | Erzeugt aus der nativen Dokumentdarstellung eine grafische, insbesondere PDF (ToPdf) |
SignerApi.VerifyApi |
signer.v2.api.VerifyApi |
4 / 4 | Prüfung von Zertifikaten und Signaturen (VerifyCert, VerifyP7, VerifyPdf, VerifyXml) |
Wo REST hinter gRPC zurückbleibt
Eine gRPC-Methode ohne google.api.http-Annotation bekommt keine REST-Route. Das trifft nicht nur Randfälle:
| Fehlt über REST | Warum es weh tut |
|---|---|
DocumentApi.ImportTransportDocumentFromInbox, ImportDocumentToFileAreaFromInbox |
Genau der Schritt, mit dem eingehende Dokumentversionen in den lokalen Bestand gelangen — siehe Aufrufe und Synchronisation |
DocumentApi.SendDocument, DeliverDocument |
Versand im ZEDAL-Verteilweg |
FileApi.CreateNewFile, GrantAccessToFile, MergeFiles, MoveDocumentToFile |
Aktenverwaltung im Nachweis-Bereich |
PreviewApi.ListTransportDocuments, ListFiles, ListFileAreaDocuments, ListInboxDocuments; QueryApi.ListFiles, ListFileAreaDocuments |
Akten und Nachweis-Bereich lassen sich über REST nicht auflisten. Bestand, Eingang und Muster listet über REST die QueryApi (ListTransportDocuments, ListInboxDocuments, ListTransportTemplates) |
Wenn du eine reine REST-Integration planst, prüfe früh, ob dein Ablauf ohne diese Operationen auskommt — das ist eine Architekturentscheidung, keine Detailfrage. Verbindlich ist immer das OpenAPI-Dokument des laufenden Systems: Was dort steht, ist über REST erreichbar; was fehlt, nicht.
Externe Anbindungen¶
Die DiWaSS-Services vermitteln serverseitig an das EU-DiWaSS-Zentralsystem und kapseln dabei Transport und Format-Konvertierung. Aus Integrator-Sicht ist diese Vermittlung Implementierungsdetail — du arbeitest gegen die ZEDAL-API.
Was nicht gekapselt ist: Betriebsregeln und Laufzeit
Zwei Dinge dringen durch die Kapselung durch, und beide muss deine Anwendung tragen:
- Die Europäische Kommission verlangt sequenzielle Aufrufe gegen DiWaSS und behält sich bei fortgesetztem Verstoß die Sperrung des API-Zugangs vor.
- Antworten kommen asynchron und langsam. Fremd-Updates erscheinen erst nach etwa zwei bis drei Minuten im ZEDAL-Bestand; der Client-Default-Timeout des SDK von 30 Sekunden reicht für DiWaSS-Pfade nicht.
Beides steht ausführlich unter Aufrufe und Synchronisation.
Single Source of Truth¶
Die .proto-Definitionen sind der Ausgangspunkt für alles: Änderungen an der API erfolgen auf Proto-Ebene. Für Integratoren heißt das:
- gRPC ist die vollständige Oberfläche. REST ist eine Projektion darauf und deckt sie fast, aber nicht vollständig ab.
- Das OpenAPI-Dokument entsteht zur Laufzeit aus den gRPC-Definitionen und beschreibt damit immer den laufenden Stand.
- Versionierung des .NET-SDK folgt Semantic Versioning (
Zedal.Sdk).
Deprecations schlagen nicht in jeden Zugriffsweg durch
Veraltete Operationen sind in den Protos mit deprecated markiert und im SDK als [Obsolete] sichtbar. Im laufenden OpenAPI-Dokument ist derzeit keine Operation als deprecated gekennzeichnet — verlass dich für die Abkündigung also nicht auf die REST-Referenz allein. Maßgeblich sind die Release-Notes des SDK und die Proto-Definitionen.
Wo es weitergeht¶
- Erste Schritte — Authentifizierung, Konfiguration, erster Aufruf
- Aufrufe und Synchronisation — Aufruffrequenz, Fehlerbehandlung, Abgleich, Zeitbudgets
- Speicherbereiche — Inbox, Nachweis-Bereich, Versandpapier-Bereich; das Vokabular hinter den meisten Core-Aufrufen
- DiWaSS-Anleitungen — aktueller Schwerpunkt: grenzüberschreitende Abfallverbringung
- Glossar — Begriffe und Abkürzungen
- .NET SDK — Quickstart für die C#-Welt