Zielstellung
Teilnehmende an der Antibiotika Resistenz Surveillance (ARS) können mit dem Feature Bulk-Upload große Mengen von retrospektiven Sendungen übermitteln. Für solche großen Datenmengen sollte nicht der ARS-Endpunkt für den synchronen Normalbetrieb genutzt werden, da dieser über ein striktes Rate Limiting verfügt und die Verarbeitung der Sendungen synchron erfolgt, so dass bei zahlreichen Sendungen mit einer großen Dauer des Uploads zu rechnen ist. Nachfolgend werden die Schnittstellen für den ARS-Bulk-Upload beschrieben.
Vorbereitung
- Es wurden entsprechende Zugänge (Testumgebung) beantragt
- Die Integration der DEMIS Schnittstelle wurde auf der Testumgebung erfolgreich getestet.
- Authentifizierung über geeignetes Verfahren in der DEMIS Schnittelle (Beispielsweise Zertifikat) ist möglich.
- Der Upload über die Synchrone Schnittstelle ist erfolgreiche implementiert worden.
- Hinweis:
Clients müssen in der Lage sein GZIP-komprimierte Responses zu verarbeiten, da insbesondere die Ergebnisse der Batch-Verarbeitung komprimiert an die Clients übertragen werden. Der Client zeigt an, dass er in der Lage ist GZIP-komprimierte Responses zu verarbeiten, indem er im Request den Header "Accept-Encoding: gzip" setzt.
Übersicht des Ablaufs
Übersicht Endpunkte
| Umgebung | Basis-URL |
|---|---|
| Produktion | https://demis.rki.de/surveillance/antibiotic-resistance/ |
| Test / Integration | Informationen: Endpunkte, Zertifikate, User und Passwort |
| Type | Route |
|---|---|
| POST | /v1/batch/fhir/bundle |
| POST | /v1/batch/upload/{batchId} |
| POST | /v1/batch/fhir/bundle/{batchId}/$close |
| GET | /v1/batch/fhir/bundle/{batchId}/$statistics |
| GET | /v1/batch/fhir/bundle/{batchId}/$results |
| POST | /v1/fhir/$process-notification (für ARS - Upload der Sendungen (synchron)) |
Bitte beachten Sie, dass v1 als Schnittstellenversion für jeden Request verwendet werden muss.
Verarbeitungsschritte
Schritt 1: Erzeugung eines leeren Batch Bundles zum Start des Bulk Uploads
Zunächst wird ein neuer Batch Job angelegt. Das erfolgt über eine FHIR create Operation durch Senden eines leeren Batch Bundles, d.h. ohne Entries.
POST /surveillance/antibiotic-resistance/v1/batch/fhir/bundle
Content-Type: application/fhir+json
{
"resourceType" : "Bundle",
"type" : "batch"
}
Der ARS-Bulk-Service antwortet mit dem erzeugten Batch Bundle, welches die Id des Jobs als Id der Bundle Ressource enthält. Unter Bundle.link.url findet der Client die URL des Endpunktes an den die ARS-Sendungen übertragen werden müssen.
HTTP/1.1 201 Created
{
"resourceType" : "Bundle",
"id": 42,
"meta" : {
"lastUpdated" : "2025-11-18T01:45:30Z"
},
"relation" : "batch",
"link": {
"relation": "edit",
"url": "https://demis.rki.de/surveillance/antibiotic-resistance/v1/batch/upload/<UUID>"
}
}
Achtung: Batches werden, wenn sie nicht geschlossen wurden, für eine Dauer von 14 Tagen offen gehalten und stehen anschließend nicht mehr zur Verfügung.
Schritt 2: Hinzufügen der ARS Sendungen zum Job
Danach werden zyklisch die ARS Sendungen übertragen. Das erfolgt durch einen POST-Request, welcher die ARS-Sendungen als ndjson beinhaltet. Je Request können Sendungen bis zu einer maximalen Request-Größe von 10 MB übertragen werden.
Bitte verwenden Sie hierfür unverändert die gleiche FHIR-Struktur, die Sie auch für die synchrone Schnitstelle verwenden. Wandeln Sie diese jedoch in ein ndjson um.
Für den Fall, dass ein HTTP-Request nicht (vollständig) verarbeitet werden kann ist es notwendig die Notification-Bundle-IDs im HTTP-Header zu übertragen. Die Reihenfolge der IDs im Header muss dabei mit der Reihenfolge der IDs der Sendungen in der FHIR-Ressource übereinstimmen. Falls beispielsweise Sendungen von der WAF abgelehnt werden oder einzelne Sendungen nicht valide gemäß FHIR-Profil sind werden diese IDs gemeinsam mit einer kurzen Erklärung des aufgetretenen Fehlers in der Ergebnis-Statistik verauskunftet.
Umsetzungshinweis: HTTP-Requests in DEMIS haben eine maximale Größe von 10 MB. Wir empfehlen jeweils fünf Sendungen pro HTTP-Request in einem Bundle zu übertragen. Sollte der ARS-Dienst mit einem HTTP Status Code 413 "Payload Too Large" oder 431 "Request Header Fields Too Large" antworten, dann bitte die Sendungen einzeln übertragen.
Request:
POST /surveillance/antibiotic-resistance/v1/batch/upload/<UUID>
Content-Type: application/fhir+ndjson
X-Document-Ids: EC857E2C-4863-436E-82AF-6E7F6A9307CE,08E73CB0-AA5A-4A02-85A4-CD8D7B8C2EB5,...
{"resource": {"resourceType": "Bundle","id": "90F0F3A5-4D36-4AD1-8D2E-1879887F4468","meta": {"profile": ["https://demis.rki.de/fhir/ars/StructureDefinition/Bundle"]},"type": "document", ... \n
{"resource": {"resourceType": "Bundle","id": "3f1ae7ab-9c21-4619-b9b9-0e746edc6eab","meta": {"profile": ["https://demis.rki.de/fhir/ars/StructureDefinition/Bundle"]},"type": "document", ... \n
{"resource": {"resourceType": "Bundle","id": "4cc94192-70e4-49b6-81b2-67e4031246e6","meta": {"profile": ["https://demis.rki.de/fhir/ars/StructureDefinition/Bundle"]},"type": "document", ... \n
{"resource": {"resourceType": "Bundle","id": "7625a51c-48bb-47c2-b37c-574d3621ec5f","meta": {"profile": ["https://demis.rki.de/fhir/ars/StructureDefinition/Bundle"]},"type": "document", ... \n
{"resource": {"resourceType": "Bundle","id": "fb22c8b0-6197-4709-b920-f92c5af1b2e8","meta": {"profile": ["https://demis.rki.de/fhir/ars/StructureDefinition/Bundle"]},"type": "document", ... \n
Im Erfolgsfall wird jeder dieser POST-Requests einfach mit HTTP-Status 202 OK beantwortet.
HTTP/1.1 202 OK
Fehlersituationen
| Ursache | HTTP-Status-Code | Beschreibung |
|---|---|---|
| Ungültige Anzahl oder Format von Document-IDs im Header | 400 Bad Request | Die Anzahl der übertragenen Document-IDs im HTTP-Header X-Document-Ids stimmt nicht mit der Anzahl der ARS-Sendungen überein. Der Request ist zu korrigieren und erneut zu senden. |
| Es ist ein Fehler bei der internen Verarbeitung aufgetreten | 500 Internal Server Error | Eine oder mehrere Nachrichten konnten durch interne Fehler nicht verarbeitet werden. Der Request ist erneut zu senden. |
Im Fehlerfall kann es in der Statistik zu Duplikationen kommen. Dies kann ignoriert werden.
Schritt 3: Upload abschließen
Wurden alle ARS-Bundle-Sendungen übermittelt, wird der Batch-Upload abgeschlossen.
POST /surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID>/$close Content-Type: application/fhir+json Content-Length: 0
Die Übertragung der Sendungen ist abgeschlossen, was durch den HTTP-Status 202 "Accepted" signalisiert wird. Die Response enthält im HTTP-Header Content-Location die URL des Endpunktes, über welche das Ergebnis des Batch Jobs abgerufen werden kann. Nach welcher Zeit zuerst das Ergebnis abgefragt werden sollte, steht im retry-after header.
HTTP/1.1 202 Accepted Content-Location: https://demis.rki.de/surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID>/$statistics retry-after: 300
Hinweise:
- Batches, die nicht explizit geschlossen wurden, werden nach einem Timeout implizit im Backend geschlossen.
- Ein Abfragen der Ressource mittels HTTP GET auf https://demis.rki.de/surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID> wird nicht unterstützt, da die Ressource potenziell mehrere dutzend Gigabytes groß werden kann.
Schritt 4: Abfrage der Ergebnisse des Jobs
Die Ergebnisse des Batch Jobs können mittels GET-Request auf den Statistik-Endpunkt der Ressource abgefragt werden:
GET /surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID>/$statistics
Wenn der Job noch nicht abgeschlossen ist, wird weiterhin der HTTP-Status 202 Accepted zurück geliefert und ein Progress-Status.
HTTP/1.1 202 Accepted X-Total: 100000 X-Progress: 20% Retry-After: 1800
Der Statistik-Endpunkt wird dann im Polling so oft aufgerufen bis das Ergebnis des Jobs zurück geliefert wird. Über den Header "Retry-After" wird der Client informiert, nach wie vielen Sekunden der nächste Request an den Statistik-Endpunkt gesendet werden sollte. Es ist zu beachten, dass ein grobes Missachten des Retry-After-Headers dazu führt, dass Anfragen an den Endpunkt abgelehnt werden. X-Total verauskunftet die Gesamtanzahl der Nachrichten im Batch. Der Header X-Progress gibt an, wie viel Prozent der Nachrichten bereits verarbeitet wurden.
GET /surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID>/$statistics
Wurden alle Sendungen des Batches verarbeitet, dann wird das Ergebnis als Ressource vom Typ Parameters mit HTTP-Status 200 OK zurück geliefert.
HTTP/1.1 200 OK
{
"resourceType": "Parameters",
"parameter": [
{ "name": "batchId", "valueString": "<UUID>" },
{ "name": "batchClosedAt", "valueDateTime": "2025-10-23T09:15:59Z" },
{ "name": "resultsAvailableUntil", "valueDateTime": "2025-10-24T09:15:59Z" },
{ "name": "total", "valueInteger": 1000000 },
{
"name": "success",
"part": [
{ "name": "url", "valueUri": "https://[...]/surveillance/antibiotic-resistance/v1/batch/fhir/bundle/42/$results?query=success" },
{ "name": "contentType", "valueString": "text/csv" },
{ "name": "count", "valueInteger": 995000 }
]
},
{
"name": "error",
"part": [
{ "name": "url", "valueUri": "https://[...]/surveillance/antibiotic-resistance/v1/batch/fhir/bundle/42/$results?query=error" },
{ "name": "contentType", "valueString": "text/csv" },
{ "name": "count", "valueInteger": 5000 },
{
"name": "countsByErrorCode",
"part": [
{ "name": "WAF", "valueInteger": 1500 },
{ "name": "VALIDATION", "valueInteger": 3200 },
{ "name": "INVALID", "valueInteger": 20 },
{ "name": "INTERNAL_ERROR", "valueInteger": 280 }
]
}
]
}
]
}
Das Ergebnis der Batch-Verarbeitung wird als Statistik zurückgegeben. Die IDs der Sendungen, die erfolgreich verarbeitet werden konnten, können über den Link in parameter.where(name = 'success').part.where(name = 'url').value als CSV heruntergeladen werden. Die Einzelergebnisse für die Sendungen, die nicht erfolgreich verarbeitet werden konnten, können über den Link in parameter.where(name = 'error').part.where(name = 'url').value abgerufen werden. Um Netzwerk-Bandbreite zu sparen sollen die Detail-Ergebnisse gzip-komprimiert abgefragt werden. Dazu ist der HTTP-Header Accept-Encoding mit dem Wert gzip zu setzen. Wenn der Header nicht gesendet wird, werden die Detail-Ergebnisse unkomprimiert übertragen.
GET /surveillance/antibiotic-resistance/v1/batch/fhir/bundle/<UUID>/$results?query=success Accept-Encoding: gzip
Document id (Client);Document id (RKI);Validation warnings 8C6DAAAD-82F6-46BA-A0E6-078AAF04BA63;295afbb4-c975-4b65-b236-d735e39c9812;40 19FEA1D7-64DF-49A3-9DD6-889624C2FD6E;275192e7-5183-4a4c-b16d-c345f24e0d17;26
GET /surveillance/antibiotic-resistance/v1/batch/fhir/bundle/42/$results?query=error Accept-Encoding: gzip
Document id (Client);Error reason;Validation errors;Validation warnings;Details A427CB93-D739-4E21-A5A1-465F95C68D83;VALIDATION;1;53; 19FEA1D7-64DF-49A3-9DD6-889624C2FD6E;INVALID;;;INVALID_PSEUDONYMS 232CEB29-3667-4407-BA04-5161BB399BB7;WAF;;; 1F15D1E1-FE25-4346-BA8E-9BC0F1BC3CC9;VALIDATION;1;105; 40461B4C-54B5-4B0E-9D17-AFC7E15044C3;VALIDATION;1;40; 3C1A577C-B436-447F-BF43-FBADDD4EF872;WAF;;;