Bundle
Model Bundle jest globalnym, wspólnym zasobem integracyjnym standardu Kamsoft.FAIR. Wzorowany jest na FHIR Bundle, ale w uproszczonej postaci przeznaczonej do wymiany żądań i odpowiedzi między modułami API.ERP.
Bundle nie dziedziczy po DomainResource — jest osobnym typem transportowym (envelope).
1. Zakres i zastosowanie
Bundle jest samodzielnym zasobem integracyjnym i pełni rolę lekkiego zestawu dla scenariuszy, w których jedna wiadomość przenosi:
- typ zestawu wymiany (
typejako prosty code), - sekcję request z listą operacji (opcjonalnie),
- sekcję response z uproszczonym statusem wyniku i listą operacji wynikowych,
- każda operacja zawiera
method,url(URI do referowania wewnętrznego) orazresource(lub payload zdarzenia — patrz trybmessage).
Model nie implementuje pełnej semantyki FHIR Bundle.entry[]. Zamiast tego upraszcza strukturę do dwóch sekcji biznesowych: request i response.
Zasada agnostyczności typu zasobu
Pole type określa sposób obsługi zestawu, a nie rodzaj przenoszonych danych. W request.items / response.items (tryby collection, batch, transaction, document) może znaleźć się dowolny DomainResource — np. Party, ProductDefinition, Document, InventoryDocument, Employment itd.
2. Typy bundle (type)
Dozwolone wartości type:
| Wartość | Semantyka (skrót) |
|---|---|
collection |
Zbiór zasobów w odpowiedzi (odczyt) |
batch |
Wiele operacji CRUD — każda niezależnie |
transaction |
Wiele operacji CRUD — jedna transakcja (all-or-nothing) |
message |
Zdarzenia integracyjne — nie model CRUD zasobów |
document |
Spójny zestaw zasobów tworzących jedną całość dokumentową |
W modelu JSON pole type jest prostym kodem, wzorowanym na FHIR code.
2.1 collection — zbiór elementów w odpowiedzi
| Aspekt | Opis |
|---|---|
| Cel | Opakować wynik zapytania — lista zasobów zwróconych w jednej odpowiedzi |
| Kierunek | Głównie response; request opcjonalny (kryteria wyszukiwania) |
| Atomowość | Brak — brak operacji zapisu, tylko agregacja odczytu |
| Obsługa items | Każdy element to niezależny wynik; brak wspólnej transakcji |
response.status |
Zwykle success; partial gdy część elementów nie została dołączona (np. brak uprawnień do pojedynczego rekordu) |
Typowe użycie: stronicowany wynik GET kolekcji, wyszukiwanie z wieloma trafieniami, zestawienie powiązanych zasobów zwróconych klientowi w jednym payloadzie.
2.2 batch — niezależna obsługa zasobów wewnątrz
| Aspekt | Opis |
|---|---|
| Cel | Wykonać wiele operacji CRUD w jednym żądaniu HTTP |
| Atomowość | Brak — operacje są niezależne |
| Wynik | response.status: success, partial lub failure |
| Rollback | Nie — udane operacje pozostają zatwierdzone; nieudane zwracają błąd per item |
| Per-item | Każdy element response.items odpowiada pozycji z request.items; method może być error przy niepowodzeniu pojedynczej operacji |
Typowe użycie: masowy import lub synchronizacja wielu zasobów z systemu zewnętrznego, gdzie błąd jednej pozycji nie powinien cofać pozostałych.
2.3 transaction — akcje w kontekście jednej transakcji
| Aspekt | Opis |
|---|---|
| Cel | Wykonać wiele operacji CRUD jako jedna transakcja biznesowa |
| Atomowość | Tak — all-or-nothing |
| Wynik | success tylko gdy wszystkie operacje się powiodły; w przeciwnym razie failure i rollback całości |
| Referencje wewnętrzne | urn:uuid: w url do powiązań między tworzonymi zasobami w ramach tego samego bundle (np. Party → PartyRole) |
Typowe użycie: utworzenie powiązanych zasobów, które muszą wejść do systemu razem; operacje wymagające spójności referencyjnej w jednym kroku.
2.4 message — obsługa zdarzeń, nie zasobów
| Aspekt | Opis |
|---|---|
| Cel | Przenosić komunikaty / zdarzenia integracyjne (pub/sub, webhooki, kolejki) |
| Zawartość | Payload nie jest modelem CRUD zasobów; zawiera typ zdarzenia, metadane, opcjonalnie referencje do zasobów |
| Odróżnienie | collection, batch, transaction, document operują na DomainResource w modelu żądanie/odpowiedź; message służy powiadomieniu o zdarzeniu — konsument sam pobiera zasoby, jeśli potrzebuje |
| Kierunek | Zwykle jednokierunkowy (event); request lub response zależnie od profilu integracji |
Elementy items w trybie message mogą nie być pełnymi DomainResource — struktura zależy od profilu zdarzenia (np. eventType, occurredAt, subject jako Reference).
2.5 document — spójna całość dokumentowa
| Aspekt | Opis |
|---|---|
| Cel | Zestaw zasobów tworzących jedną spójną całość (jedno źródło prawdy) |
| Zawartość | Dowolne DomainResource powiązane semantycznie (np. dokument + pozycje w contained, dokument + załączniki) |
| Atomowość | Zależy od profilu i kontraktu API — często jak transaction przy zapisie |
3. Porównanie trybów
| Tryb | Co niesie items |
Atomowość zapisu | Typowy kierunek |
|---|---|---|---|
| collection | dowolne DomainResource (odczyt) | — (brak zapisu) | response |
| batch | dowolne DomainResource (CRUD) | nie — partial OK | request → response |
| transaction | dowolne DomainResource (CRUD) | tak — all-or-nothing | request → response |
| message | zdarzenia (nie pełny CRUD) | zależy od brokera | asynchroniczny flow |
| document | dowolne DomainResource (spójna całość) | zależy od profilu | request i/lub response |
4. Struktura Bundle
| Nazwa | Kard. | Typ | Opis |
|---|---|---|---|
| resourceType | 0..1 | string | Bundle (konwencja REST) |
| type | 1..1 | code | collection, batch, transaction, message, document |
| identifier | 0..* | Identifier | Identyfikator zestawu (opcjonalnie) |
| comment | 0..1 | string | Opis zestawu |
| request | 0..1 | BundleSection | Sekcja żądania |
| response | 0..1 | BundleSection | Sekcja odpowiedzi |
Co najmniej jedna z sekcji request lub response powinna być obecna (zależnie od trybu i kierunku wymiany).
5. Sekcja request
Sekcja request zawiera minimalne informacje potrzebne do opisania intencji operacji:
| Nazwa | Kard. | Typ | Opis |
|---|---|---|---|
| items | 1..* | BundleItem[] | Lista operacji request |
| items[].method | 1..1 | code | Operacja: create, read, update, delete |
| items[].url | 1..1 | uri | Wewnętrzny identyfikator URI (ResourceType/id lub urn:uuid:…) |
| items[].resource | 0..1 | DomainResource | object | Zasób lub payload (w message — struktura zdarzenia) |
method opisuje zamiar biznesowy, a nie bezpośrednio metodę HTTP.
6. Sekcja response
Sekcja response zawiera wynik przetwarzania żądania:
| Nazwa | Kard. | Typ | Opis |
|---|---|---|---|
| status | 1..1 | string | Wynik zestawu: success, partial, failure |
| detail | 0..1 | string | Zwięzły opis wyniku lub błędu |
| items | 0..* | BundleItem[] | Lista operacji response |
| items[].method | 1..1 | code | Operacja powiązana z wejściową lub error przy błędzie pozycji (batch) |
| items[].url | 1..1 | uri | Wewnętrzny identyfikator URI |
| items[].resource | 0..1 | DomainResource | object | Zasób wynikowy lub szczegóły błędu / zdarzenia |
status pozostaje domenowy i uproszczony. Mapowanie na kody HTTP powinno być opisane na poziomie kontraktu API, a nie w samym modelu zasobu.
Reguły response.status:
batch:success— wszystkie OK;partial— część OK;failure— wszystkie nieudanetransaction:successlubfailure(bezpartial)collection: zwyklesuccess;partialgdy nie wszystkie elementy mogły zostać zwrócone
7. Przykłady
7.1 transaction — powiązane zasoby (all-or-nothing)
{
"resourceType": "Bundle",
"type": "transaction",
"request": {
"items": [
{
"method": "create",
"url": "urn:uuid:party-1",
"resource": {
"resourceType": "Party",
"id": "party-001",
"comment": "Nowy podmiot biznesowy"
}
},
{
"method": "create",
"url": "urn:uuid:party-role-1",
"resource": {
"resourceType": "PartyRole",
"id": "pr-001",
"comment": "Rola podmiotu: dostawca",
"owner": [{ "system": "internal-reference", "value": "urn:uuid:party-1" }]
}
}
]
},
"response": {
"status": "success",
"detail": "Wszystkie obiekty zostały utworzone pomyślnie.",
"items": [
{
"method": "create",
"url": "urn:uuid:party-1",
"resource": {
"resourceType": "Party",
"id": "party-001",
"meta": { "lastModified": "2026-05-29T10:15:00Z" }
}
},
{
"method": "create",
"url": "urn:uuid:party-role-1",
"resource": {
"resourceType": "PartyRole",
"id": "pr-001",
"meta": { "lastModified": "2026-05-29T10:15:01Z" }
}
}
]
}
}
7.2 collection — zbiór zasobów w odpowiedzi
{
"resourceType": "Bundle",
"type": "collection",
"identifier": [{ "value": "search-parties-active" }],
"response": {
"status": "success",
"items": [
{
"method": "read",
"url": "Party/party-001",
"resource": { "resourceType": "Party", "id": "party-001", "comment": "Kontrahent A" }
},
{
"method": "read",
"url": "Party/party-002",
"resource": { "resourceType": "Party", "id": "party-002", "comment": "Kontrahent B" }
}
]
}
}
7.3 batch — niezależne operacje (partial OK)
{
"resourceType": "Bundle",
"type": "batch",
"request": {
"items": [
{
"method": "update",
"url": "ProductDefinition/pd-001",
"resource": { "resourceType": "ProductDefinition", "id": "pd-001", "name": "Towar A (nowa nazwa)" }
},
{
"method": "create",
"url": "urn:uuid:pd-new",
"resource": { "resourceType": "ProductDefinition", "id": "pd-999", "name": "Towar nowy" }
}
]
},
"response": {
"status": "partial",
"detail": "1/2 operacji zakończonych powodzeniem",
"items": [
{
"method": "update",
"url": "ProductDefinition/pd-001",
"resource": { "resourceType": "ProductDefinition", "id": "pd-001", "name": "Towar A (nowa nazwa)" }
},
{
"method": "error",
"url": "urn:uuid:pd-new",
"resource": {
"resourceType": "OperationOutcome",
"comment": "Duplikat identyfikatora"
}
}
]
}
}
7.4 message — zdarzenie integracyjne
{
"resourceType": "Bundle",
"type": "message",
"identifier": [{ "value": "evt-2026-00042" }],
"response": {
"status": "success",
"items": [
{
"method": "event",
"url": "Document/doc-invoice-001",
"resource": {
"eventType": "DocumentPosted",
"occurredAt": "2026-06-01T14:30:00Z",
"subject": { "reference": "Document/doc-invoice-001", "type": "Document" }
}
}
]
}
}
8. Odniesienia
- DomainResource — typ bazowy elementów w trybach
collection,batch,transaction,document - Identifier, Reference
- FHIR R5 – Bundle