Voorstellen t.b.v. de ZGW API performance verbeteringen #1960
Replies: 5 comments 2 replies
-
Uit mijn gist die eerder opgesteld was. Ik heb nog wat gedachten hierbij die ik maandag ga aanvullen. Optimizing the ZGW API's for reading ⚡Below is a proposal and example of how the ZGW API's (2.0?) can be optimized for reading Observed problem(s)
Example request and responseAs an example, we can use the (common) case of retrieving a list of Variant 1: inclusions mechanism GET /api/v2/zaken?include=status,zaaktype HTTP/1.1
Host: zaken-api.vng.cloud
Authorization: Bearer abcdefg.ijkl.mnop Note the A response would look like this: {
"count": 2,
"next": null,
"previous": null,
"data": [
{
"url": "https://zaken-api.vng.cloud/api/v2/zaken/d0e7c478",
"zaaktype": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"identificatie": "zaak-001",
"omschrijving": "Voorbeeldzaak 1",
"status": "https://zaken-api.vng.cloud/api/v2/statussen/2e4eeaa5"
},
{
"url": "https://zaken-api.vng.cloud/api/v2/zaken/05da0e11",
"zaaktype": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"identificatie": "zaak-002",
"omschrijving": "Voorbeeldzaak 2",
"status": "https://zaken-api.vng.cloud/api/v2/statussen/8a564101"
}
],
"inclusions": {
"zaken.status": [
{
"uuid": "2e4eeaa5",
"url": "https://zaken-api.vng.cloud/api/v2/statussen/2e4eeaa5",
"zaak": "https://zaken-api.vng.cloud/api/v2/zaken/d0e7c478",
"statustype": "https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"datumStatusGezet": "2022-02-24T14:15:22Z",
"statustoelichting": ""
},
{
"uuid": "8a564101",
"url": "https://zaken-api.vng.cloud/api/v2/statussen/8a564101",
"zaak": "https://zaken-api.vng.cloud/api/v2/zaken/05da0e11",
"statustype": "https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"datumStatusGezet": "2022-01-23T08:43:00Z",
"statustoelichting": ""
}
],
"catalogi.zaaktype": [
{
"url": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"catalogus": "https://catalogi-api.vng.cloud/api/v2/catalogi/4e851f9d",
"identificatie": "456",
"omschrijving": "Zaaktype 456",
"statustypen": [
"https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"https://catalogi-api.vng.cloud/api/v2/statustypen/7e33d7ac",
],
}
],
}
} The response now has an enveloppe with the regular pagination parameters, and the In this example, both cases in the result list have the same zaaktype, so the included Note also that to obtain the zaaktype information, an API boundary must be crossed - Variant 2: deep inclusions The second variant expands on the first one by requesting nested inclusions. In variant GET /api/v2/zaken?include=status,status.statustype,zaaktype HTTP/1.1
Host: zaken-api.vng.cloud
Authorization: Bearer abcdefg.ijkl.mnop Response: {
"count": 2,
"next": null,
"previous": null,
"data": [
{
"url": "https://zaken-api.vng.cloud/api/v2/zaken/d0e7c478",
"zaaktype": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"identificatie": "zaak-001",
"omschrijving": "Voorbeeldzaak 1",
"status": "https://zaken-api.vng.cloud/api/v2/statussen/2e4eeaa5"
},
{
"url": "https://zaken-api.vng.cloud/api/v2/zaken/05da0e11",
"zaaktype": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"identificatie": "zaak-002",
"omschrijving": "Voorbeeldzaak 2",
"status": "https://zaken-api.vng.cloud/api/v2/statussen/8a564101"
}
],
"inclusions": {
"zaken.status": [
{
"uuid": "2e4eeaa5",
"url": "https://zaken-api.vng.cloud/api/v2/statussen/2e4eeaa5",
"zaak": "https://zaken-api.vng.cloud/api/v2/zaken/d0e7c478",
"statustype": "https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"datumStatusGezet": "2022-02-24T14:15:22Z",
"statustoelichting": ""
},
{
"uuid": "8a564101",
"url": "https://zaken-api.vng.cloud/api/v2/statussen/8a564101",
"zaak": "https://zaken-api.vng.cloud/api/v2/zaken/05da0e11",
"statustype": "https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"datumStatusGezet": "2022-01-23T08:43:00Z",
"statustoelichting": ""
}
],
"catalogi.zaaktype": [
{
"url": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"catalogus": "https://catalogi-api.vng.cloud/api/v2/catalogi/4e851f9d",
"identificatie": "456",
"omschrijving": "Zaaktype 456",
"statustypen": [
"https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"https://catalogi-api.vng.cloud/api/v2/statustypen/7e33d7ac",
],
}
],
"catalogi.statustype": [
{
"url": "https://catalogi-api.vng.cloud/api/v2/statustypen/0e670d281",
"omschrijving": "Aanvraag ontvangen",
"zaaktype": "https://catalogi-api.vng.cloud/api/v2/zaaktypen/d2feda7f",
"volgNummer": 1,
"isEindstatus": false
}
]
}
} The response gained just a little bit extra data compared to Variant 1: the inclusion Theoretically, if you were to also request the inclusion Variant 3 There could be room for an Considerations worth mentioningThe include mechanism works for resources across APIs, but doesn't have to. Implementations such as Open Zaak that have all the data in a single database can This moves the data-fetching from the consumer to the provider side, reducing complexity Challenge: forwarding the credentials/permissions to the external APIs to ensure the The include mechanism is granular enough for (advanced) clients The dotted-path lookup mechanism lets the client decide how deep the data should be Potential for caching at provider side When looking up relations across API boundaries, a network call overhead is incurred. The Autorisaties API can be queried by a Zaken API to determine which of that (cached) Tried and tested mechanism The mechanism is in production use and implemented in a library: While designing this pattern, ideas have been borrowed from HAL, GraphQL and json-api. Other solutions consideredHAL Standard proposal has been in limbo for a long time, and is considered too verbose, GraphQL GraphQL is very suitable for clients who want to control which data is returned in The inclusions mechanism partially tackles this - it stays true to RESTful principles json-api json-api is a strict HATEOAS implementation and defines a complex, recursive schema for The inclusions mechanism is heavily inspired by json-api and aims to be a more ?expand parameter It helps to reduce network calls needing to be made, but in the case of (heavily) The inclusions mechanism combats this by hoisting the "expanded" resources and Edits/amendments 21-03-2022 Boundaries of inclusionsWe cannot expect the ZGW API's to "know the entire world", by which I mean they cannot possibly be aware or be updated all the time for API/resource definitions in other domains that may be tangentially related. Think of the BRP, but also BAG API or any other API/resource that may be connect to a "ZAAK". In my opinion, the boundaries for inclusions are limited to the domain of the ZGW API's. This means that Zaken API can include Zaaktypen and related resources, but not a "Natuurlijk persoon" who happens to be the "initiator" of the "ZAAK". We can even make this more specific by tying it to the performed input validations. If a resource needs to be fetchable to validate it, then it can be included, otherwise not. For those resources to further simplify client development, you could consider a convenience API that sits on top of the ZGW API's, but I doubt that this will be easy to standardize and define completely upfront. Those API's are very application dependent, and you don't want to bloat them and cause cognitive and maintenance overload with stuff of other domains that is not even relevant. If you are only using 10% of an API definition, I'm afraid that API definition is too big. I'm also not confident that you can specify a filtering/searching API that can cover all particular edge cases needed, so I'm still in favour of leaving that to the client application and domain. |
Beta Was this translation helpful? Give feedback.
-
Nog een alternatief: Breid de GET uit met alle gerelateerde resources binnen dezelfde API voor het hoofdobject. Dit stelt ons in staat om bijvoorbeeld bij een Deze change kan zelfs backwards compatibel worden gedaan en zou een hoop calls schelen. Eigenlijk hanteer je dan "Haal Centraal" op de hoofd objecten: Zaak in Zaken API, Informatieobject in Documenten API, en de Catalogi API zijn het er 3: Zaaktype, Informatieobjecttype en Besluittype. |
Beta Was this translation helpful? Give feedback.
-
Een voorbeeld uit de praktijk valt te vinden op: Sudwest-Fryslan/OpenZaakBrug#323 (met tijdsduur erbij) |
Beta Was this translation helpful? Give feedback.
-
Ik heb dit op OpenAPI 3.0 niveau uitgewerkt in de Zaken API, dit geeft een voorbeeld hoe de API documentatie er dus uit ziet met inclusions: Aandachtspunten:
Screenshots: OAS code: https://github.com/maykinmedia/zaken-api/blob/feature/poc-inclusions-api-spec/src/openapi.yaml#L3241 |
Beta Was this translation helpful? Give feedback.
-
Ik was nog wat verder aan het denken over het HAL voorbeeld en het zit me nog steeds niet lekker om dat te gaan toepassen.
Ik ben overigens ook erg benieuwd naar de (inhoudelijke) motivering om HAL wél in andere APIs toe te passen, en dan niet een makkelijk argument als "dat staat voorgeschreven op plaats X" - dan wil ik ook weten waarom dat staat voorgeschreven. |
Beta Was this translation helpful? Give feedback.
-
Hieronder komen voorstellen voor de ZGW APIs
Beta Was this translation helpful? Give feedback.
All reactions