Omdat van een Zaak, Informatieobject of Besluit altijd de bijbehorende definities moeten kunnen worden opgevraagd zoals die waren ten tijde van het aanmaken van die Zaak, Informatieobject of Besluit is bij het ontwikkelingen van de ZWG standaard gekozen voor het maken van nieuwe resources wanneer een type-definitie aangepast moet worden. Deze keuze, hoewel begrijpelijk gezien de tijd en kennis, heeft geleid tot een afwijking van gangbaar gedrag van API’s. Het automatische versiebeheer in de Catalogi API wijkt af van dat van de overige API’s: De resources in de Catalogi API zijn dus versies van de betreffende resources. “Zaaktype” moet gelezen worden als “Versie van een Zaaktype”, “Informatieobjecttype” is een “Versie van een Informatieobjecttype”, “Besluittype” is een “Versie van een Besluittype” etc. Dit begrip is essentieel om de Catalogi API en het historiemodel te begrijpen en correct toe te kunnen passen.
Concreet betekent dit dat wanneer van een Zaaktype een nieuwe versie gemaakt wordt een nieuwe resource wordt aangemaakt met een eigen identifier (UUID) en eigen waarden. Ditzelfde geldt voor Informatieobjecttype en Besluittype.
Nadeel hiervan is echter dat de relaties tussen de verschillende definities gelegd worden middels urls. Deze urls bevatten de UUID en wanneer een nieuwe versie van een definitie gemaakt wordt moeten ook alle definities die naar de gewijzigde definitie verwijzen aangepast worden. Dit wordt al snel een ingewikkelde kluwen van definities die lastig te beheren is.
Om dit probleem het hoofd te bieden is in Catalogi API 1.3.0 het zogenaamde historiemodel ingevoerd. Hiermee zijn we niet meer (in alle gevallen) afhankelijk van harde koppelingen op basis van url’s en hoeft één versieverandering van een hoofdtype niet meer te leiden tot een cascade van nieuwe versies van alle gerelateerde objecttypen.
Het historiemodel kent de volgende uitgangspunten:
Deze drie hoofdtypen zijn in bovenstaande afbeelding weergegeven in de kleuren groen (Zaaktype met gerelateerde objecttypen), blauw (Informatieobjecttype) en rood (Besluittype).
Elk hoofdtype kent een eigen lifecycle en kan onafhankelijk van de andere hoofdtypen doorontwikkeld worden. De uitzonderingen hierop zijn het aanmaken en beëindigen van het hoofdobjecttype.
Doordat versies van Zaaktype, Informatieobjecttype en Besluittype niet meer 1 op 1 aan elkaar gekoppeld zijn is het noodzakelijk te weten op welke datum de situatie van de gevraagde objecttypen en hun relaties getoond moeten worden. Met behulp van de (optionele) parameter datumGeldigheid kan de hele constellatie zoals geldig op die specifieke datum opgevraagd worden. Wanneer de datumGeldigheid niet expliciet meegegeven wordt geeft het antwoord de huidige constellatie, dus de situatie op het moment van aanroepen, weer.
Een versie van een Zaaktype, Informatieobjecttype of Besluittype kan ook opgevraagd worden door de identificatie (zaaktype.identificatie, informatieobjecttype.omschrijving of besluittype.omschrijving) en de gewenste datumGeldigheid mee te geven. In situaties waarin wel de identificatie van een objecttype bekend is maar niet de exacte UUID of url is het dan toch mogelijk de correcte versie op te vragen.
De datumGeldigheid is vanuit de zaak geredeneerd de registratiedatum van de zaak.
Bij een versie van een Zaaktype kan slechts één versie van onderstaande gerelateerde objecttypen worden vastgelegd.
Zaaktype kent de volgende gerelateerde objecttypen:
In dit voorbeeld is de eerste versie v1 van zaaktype ZT1 gepubliceerd op 1 januari 2023. Deze versie van het Zaaktype is via het attribuut “Besluittype.omschrijving” gekoppeld met besluittype BT1. Op het moment van verwijzing bestond alleen versie v1 van het besluittype BT1.
Op 1 januari 2024 wordt versie v2 van het zaaktype ZT1 gepubliceerd welke tevens wordt gekoppeld aan besluittype BT1.
Op 1 juli 2024 wordt versie v2 van het besluittype BT1 gepubliceerd. Door de losse koppeling (via “Besluittype.omschrijving” in plaats van “Besluittype.url”) kunnen beide versies van zaaktype ZT1 (v1 en v2) beiden gebruik maken van besluittype v2 hoewel deze later gepubliceerd is.
Het stippelijntje in de v1 versie van zaaktype ZT1 stelt de “eindeGeldigheid” voor: dat is de datum één dag voor de “beginGeldigheid” van het nieuwe zaaktype (v2 in dit geval). Het attribuut “eindeGeldigheid” is hier niet de eindgeldigheid van het zaaktype zelf want dat blijft altijd geldig voor de zaak waaraan het ooit gekoppeld is. Maar het is wel de eindgeldigheid voor nieuwe zaken die eraan gekoppeld kunnen worden. Dus na deze eindgeldigheid mogen er geen nieuwe zaken meer aan het zaaktype gekoppeld worden.
Hetzelfde verhaal voor het stippellijntje in het besluittype v1 van besluittype BT1, m.a.w. nieuwe zaken mogen niet gekoppeld worden aan besluittypen die niet meer geldig zijn.
Om het voorbeeld concreter te maken is in onderstaand plaatje de situatie uitgebreid met “echte” zaken en besluiten die aan zaaktype ZT1 en besluittype BT1 gekoppeld zijn. Op het moment dat zaak Z2 op 1-4-2024 gekoppeld werd aan zaaktype ZT1 bestond er nog geen versie v2 van het besluittype BT1. Pas later op 1-7-2024 werd deze BT1.v2 versie aangemaakt en op 1-9-2024 werd het besluit B2 gekoppeld aan besluittype BT1.v2 en zaak Z2.
In de volgende secties gaan we met concrete ZGW-berichten de bovenstaande situatie reconstrueren. Voor het gemak beperken we ons tot alleen de zaaktype ZT1 en besluittype BT1 en laten we de zaken, Z1 en Z2, en besluiten, B1 en B2, die gebruik maken van deze typen buiten beschouwing.
POST /besluittypen
Request:
{
"omschrijving": "BT1",
"beginGeldigheid" : "2023-01-01",
"toelichting": "Dit is versie 1 van BT1",
...
}
Response:
{
"url" : "/besluittypen/",
"omschrijving": "BT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 1 van BT1",
...
"concept": true
}
POST /besluittypen//publish
Response:
{
"url" : "/besluittypen/",
"omschrijving": "BT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 1 van BT1",
...
"concept": false
}
POST /zaaktypen
Request:
{
"identificatie": "ZT1",
"beginGeldigheid": "2023-01-01",
"toelichting": "Dit is versie 1 van ZT1",
...
"besluittypen": [ "BT1" ],
...
}
Response:
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2023-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 1 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": true
}
POST /zaaktypen//publish
Response:
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2023-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 1 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
POST /zaaktypen
Request:
{
"identificatie": "ZT1",
"beginGeldigheid": "2024-01-01",
"toelichting": "Dit is versie 2 van ZT1",
...
"besluittypen": [ "BT1" ],
...
}
Response:
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 2 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": true
}
Er kunnen niet twee zaaktypen tegelijk geldig zijn. Dus we geven het oude zaaktype een eindgeldigheid van 1 dag voor de begingeldigheid van het nieuwe zaaktype.
PATCH /zaaktypen/
Request:
{
"eindeGeldigheid": "2023-01-01"
}
Response:
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": "2023-12-31",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
POST /zaaktypen//publish
Response:
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-01-01",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
POST /besluittypen
Request:
{
"omschrijving": "BT1",
"beginGeldigheid" : "2024-07-01",
"toelichting": "Dit is versie 2 van BT1",
...
}
Response:
{
"url" : "/besluittypen/",
"omschrijving": "Besluit genomen",
"beginGeldigheid": "2024-07-01",
"toelichting": "Dit is versie 2 van BT1",
...
"concept": true
}
Er kunnen niet twee besluittypen tegelijk geldig zijn. Dus we geven het oude besluittype een eindgeldigheid van 1 dag voor de begingeldigheid van het nieuwe besluittype.
PATCH /besluittypen/
Request:
{
"eindeGeldigheid": "2024-06-30"
}
Response:
{
"url" : "/besluittypen/",
"omschrijving": "ZT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": "2024-06-30",
"toelichting": "Dit is versie 1 van BT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
POST /besluittypen/besluit-genomen-v2/publish
Response:
{
"url" : "/besluittypen/",
"omschrijving": "Besluit genomen",
"beginGeldigheid": "2024-07-01",
"toelichting": "Dit is versie 2 van BT1",
...
"concept": false
}
GET /zaaktypen?identificatie=ZT1
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": "2023-12-31",
"toelichting": "Dit is versie 1 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
},
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 2 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
]
}
In de bovenstaande query is geen parameter datumGeldigheid meegegeven en daarom krijgen we alle versies van het zaaktype Z1 terug inclusief de versie(s) die niet meer geldig zijn. Voor gerelateerde objecten in het responsbericht worden alleen de versies geretourneerd die geldig zijn op de datum waarop de query is uitgevoerd. In dit geval is de query uitgevoerd op 12-6-2025 en krijgen we versie 2 van het besluittype BT1 terug. Als we dezelfde query op 1-4-2024 hadden uitgevoerd dan was versie 1 van het besluittype BT1 weergegeven.
Let op: datumGeldigheid= is niet de default waarde van bovenstaande query want dan had je maar één versie (de geldige versie) van het zaaktype teruggekregen in plaats van alle versies (twee in dit geval). Zie dit voorbeeld als de variabele `` de waarde 1-10-2024 zou hebben, dan krijg je maar één resultaat terug.
GET /besluittypen?omschrijving=BT1
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url" : "/besluittypen/",
"omschrijving": "BT1",
"beginGeldigheid": "2023-01-01",
"eindeGeldigheid": "2024-06-30",
"toelichting": "Dit is versie 1 van BT1",
...
"zaaktypen" : [ "/besluizaaktypenttypen/" ],
...
"concept": false
},
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-07-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 2 van BT1",
...
"zaaktypen" : [ "/zaaktypen/" ],
...
"concept": false
}
]
}
GET /zaaktypen?identificatie=ZT1&datumGeldigheid=2023-04-01
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2023-01-01",
"eindeGeldigheid": "2023-12-31",
"toelichting": "Dit is versie 1 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
]
}
GET /zaaktypen?identificatie=ZT1&datumGeldigheid=2024-04-01
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 2 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
]
}
GET /zaaktypen?identificatie=ZT1?datumGeldigheid=2024-10-01
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url" : "/zaaktypen/",
"identificatie": "ZT1",
"beginGeldigheid" : "2024-01-01",
"eindeGeldigheid": null,
"toelichting": "Dit is versie 2 van ZT1",
...
"besluittypen" : [ "/besluittypen/" ],
...
"concept": false
}
]
}
In dit geval wordt versie v2 van het besluittype teruggegeven in plaats van versie v1. Immers op 1-10-2024 is de v1 versie van het besluittype niet meer geldig.