# Gebruik en migratie van URLs naar URNs

**Auteur**: Joeri Bekker | **Status**: Review

## Inleiding

In de REST API’s die vanaf de VNG API standaard voor ZGW zijn geïntroduceerd, wordt van het ene object naar een ander object, verwezen met een URL (Uniform Resource Locator). Bijvoorbeeld om aan te geven dat eaen ENKELVOUDIGINFORMATIEOBJECT bij een ZAAK hoort, of dat een ZAAK hoort bij een bepaald ZAAKTYPE.

Ter illustratie een ZAAK (in de Zaken API) van een ZAAKTYPE (in de Catalogi API):

```json
{
  "url": "<https://www.utrecht.nl/open-zaak-commutr/zaken/api/v1/zaken/b67d13>",
  "uuid": "b67d13",
  "zaakidentificatie": "ZAAK-0001",
  "zaaktype": "<https://www.utrecht.nl/open-zaak-commutr/catalogi/api/v1/zaaktypen/60aa32>",
  ...
}
```

*Voor de leesbaarheid worden UUIDs afgekort tot 6 tekens.*

URLs zijn meestal te volgen door software en, met de juiste credentials, is de inhoud (de gegevens) achter de URL ook daadwerkelijk op te halen door de software.

URLs bevatten een locatie bedoeld voor software om te volgen. De locatie van een object in register A ligt vast bij het object in register B. Bijvoorbeeld: Een ZAAK in de Zaken API bevat een locatie naar een ander register, de Catalogi API, om het ZAAKTYPE te vinden. Als software gegevens opvraagt van register A, en een URL krijg naar register B, dan moet de software ook credentials hebben om register B te bevragen.

### Probleemstelling

Het gebruik van URLs om te verwijzen naar objecten kent een aantal nadelen:

1. Een URL is niet zomaar te bevragen, je hebt hier (meestal) credentials voor nodig
2. Een URL werkt enkel met digitale registraties, en vereisen dat deze een API hebben
3. Een URL bevat een domein naam:
   1. Als het domein wijzigt, zijn alle verwijzingen ongeldig. Dit vergt aanpassingen over de gehele dataset in het gehele landschap.
   2. Het domein kan binnen of buiten de organisatie (interne/externe DNS) anders routeren, wat voor fouten of onnodig netwerk verkeer kan zorgen
   3. Bij gebruik van Gateway moeten de URLs/domeinen getransformeerd worden.
   4. Bij overhevelen van gegevens, bijv. van een acceptatie naar productie omgeving, moet de URL overal aangepast worden (variant van a).

Het grote voordeel van URLs is dat ze, exact aangeven waar de informatie beschikbaar is maar daar heb je niet zo veel aan als je toch credentials nodig hebt (en dit in je client applicatie moet matchen tegen de URL) of als de URL niet werkt.

### Doelstelling

Het doel is om te kijken of er een alternatief is dat de nadelen van URLs kan wegnemen of verkleinen.

### Oplossingsrichting

Hiertoe kijken we naar URN (Uniform Resource Name) en URI (Uniform Resource Identifier). Een voorbeeld van een URN is een ISBN (International Standard Book Number). Als URN bestaat bijvoorbeeld `urn:isbn:0-486-27557-4` wat niets zegt over waar dit boek zich bevind maar als je het register weet (de bibliotheek) kan je het vinden.

Een URI is echter vrijwel synoniem met URN maar heeft het formaat van een URL (technisch genomen, heeft een URL het formaat van een URI) en kan daarom voor verwarring zorgen. We vergelijken daarom vooral URLs en URNs. URNs bieden een aantal voordelen op de genoemde nadelen van URLs.

|                                                          | **URL**                                                          | **URN**                                  |
| -------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------- |
| **Resolve-methode (mapping)**                            | DNS                                                              | Client applicatie configuratie           |
| **Credentials**                                          | Client applicatie configuratie                                   | Client applicatie configuratie           |
| **Geschikt voor type registraties**                      | API’s                                                            | Alles (API’s, Webservices, Excel)        |
| **Wijzigingen nodig als omgeving / infra wijzigt**       | Client applicatie configuratie + (data migratie in) registraties | Client applicatie configuratie           |
| **Impact van gegevens overhevelen naar andere omgeving** | Data migratie                                                    | Client applicatie configuratie           |
| **Veiligheid**                                           | Data zonder “resolving” mogelijk onbedoeld op te vragen          | Data enkel met “resolving” op te vragen. |

URN’s bieden tevens de kans om verwijzingen op een vastgestelde structurele manier te beschrijven zonder uitspraak te doen over hoe of waar het object kan worden opgehaald.

We zien hier 2 kern-voordelen:

1. Alle configuratie benodigd om gegevens op te vragen bevind zich in de client applicatie
2. Data wordt porteerbaar, en de locatie wijzigt d.m.v. client applicatie configuratie

Een URN-formaat zou bijvoorbeeld kunnen zijn: `<organisatie>:<systeem>:<component>:<resource>:<identificatie>`. Op deze manier heb je alle gegevens die nodig zijn, door middel van de fragmenten van een URN:

* `organisatie` geeft aan bij wie het staat (idealiter vaste lijst)
* `systeem` geeft aan, met 1 en 2 erbij, waar je het kunt ophalen (flexibel)
* `component` geeft aan in welk component de resource zit (idealiter vast lijst, uit GEMMA/NORA) - Na discussie toegevoegd. In eerste instantie zou deze af te leiden zijn uit de `resource` maar er zijn wellicht toch kans op duplicaties dat wordt voorkomen met dit attribuut.
* `resource` geeft aan wat het is (idealiter vaste lijst, uit GEMMA/NORA)
* `identificatie` geeft aan hoe je dit specifieke item ophaalt (flexibel)

Het voorbeeld bovenaan, zou met URNs bijvoorbeeld worden (lees het advies voor meer voorbeelden):

```json
{
  "urn": "utrecht:zaken-sociaal:zrc:zaak:b67d13",
  "uuid": "b67d13",
  "zaakidentificatie": "ZAAK-0001",
  "zaaktype": "utrecht:zaken-sociaal:ztc:zaaktype:60aa32",
  ...
}
```

#### Landelijke registraties

Voor landelijke registraties zoals de KVK, zou een eenvoudigere URN structuur gehanteerd worden, immers zijn er geen andere systemen of organisaties. Dit is buiten scope voor nu maar ter inspiratie:

* `nl.brp:nnp:bsn:111222333`
* `nl.hr:nnp:kvk_nummer:12345678`
* `nl.hr:nnp:kvk_nummer:12345678:vestigingsnummer:12345678`
* `nl.hr:nnp:vestigingsnummer:12345678`
* `nl.hr:nnp:rsin:123456789011`

### Mogelijke consumer implementatie

In de configuratie van applicaties, moeten de API's geconfigureerd zijn en welke URN's ze aankunnen. Een mogelijke aanpak voor URN naar URL zou als volgt kunnen zijn:

**Zaken API (Afdeling Wonen)**

* Base URL: `https://www.utrecht.nl/wonen/zaken/api/v1`
* API-sleutel: `xyz`
* URN-patronen:
  * `urn:nld:gemeenteutrecht-wonen:zaak:zaaknummer:([0-9-])` -> `{baseurl}/zaken/?zaaknummer={1}[0]`
  * `urn:nld:gemeenteutrecht-wonen:zaak:uuid:([0-9a-f-]+)` -> `{baseurl}/zaken/{1}`

Met bovenstaande configuratie heb je 2 valide URN-regex patronen die door deze API-configuratie kunnen worden opgepakt. URNs op basis van `zaaknummer` en URNs op basis van de `UUID` van de zaak. De URNs worden verder gefilterd op basis van de organisatie (gemeente utrecht) aangevuld met de afdeling (wonen).

Als er dus een URN is `urn:nld:gemeenteutrecht-wonen:zaak:zaaknummer:2026-007531571` dan kan deze door de Zaken API (Afdeling Wonen) worden geresolved naar een valide URL.

### Advies

Introduceer bij nieuwe registraties enkel URNs voor verwijzingen naar buiten, om te profiteren van de voordelen zoals meer configuratie bij elkaar te houden en gegevens porteerbaar te houden. Bij bestaande registraties kan het “urn”-veld geïntroduceerd worden als experiment.

Gebruik voor het URN-formaat, voor de “vaste lijsten”, bestaande registraties. Voor `organisatie` zou dit een [OIN](https://www.logius.nl/onze-dienstverlening/toegang/centrale-oin-raadpleegvoorziening) kunnen zijn en voor `resource` de naam van de (hoofd) resource uit de API (Zaken API: ZAAK, Klantinteracties API: PARTIJ, etc.).

Een aantal voorbeelden:

* `00000001002220647000:zaken-wonen:zrc:zaak:b67d13`
* `00000001002220647000:zaak:zaken-sociaal:zrc:a8222b`
* `00000001002308836000:burgerzaken:zrc:zaak:341fa9`
* `00000001002308836000:kcc:kic:partij:7ef22c`
* `00000001002308836000:kcc:kic:internetaak:9bb51a`

#### Aanvullende adviezen

**Transitie**

Er zijn nu 2 constructies voor verwijzingen in gebruikt: URLs en Identificatoren. In principe kan aan beide constructies een “urn”-attribuut toegevoegd worden. Hiervoor zal wel per URL een mapping gemaakt moeten worden voor `organisatie` en `systeem`. De andere 2 fragmenten zouden te mappen moeten zijn zonder additionele gegevens. Bij Identificatoren zou de informatie allemaal aanwezig moeten zijn om de mapping geautomatiseerd te maken.

*Advies: Voeg het “urn”-attribuut overal toe als experimenteel.*

**Waarden van het `systeem`-fragment**

Het `systeem`-fragment is een flexibele waarde en kan dus van alles zijn. Het gevaar ligt op de loer om hier bijvoorbeeld de omgeving in op te nemen (bijvoorbeeld: `openzaak-acceptatie-commutr`). Hoewel dit kan, zou dit een nadeel van URLs teniet doen omdat het meer een “locator” wordt. Gegevens migreren van test naar acceptatie, vergt dan weer een data migratie terwijl de configuratie van de client applicatie per omgeving simpelweg al kan verschillen waardoor het overbodig is om de omgeving vast te leggen in de URN.

Je zou ook een leverancier- of product naam kunnen opnemen in de URN. Dit lijkt wellicht handig maar als gekozen wordt voor een ander product met dezelfde API’s, dan komt natuurlijk de vraag om de URN ook aan te passen, waarmee je weer een data migratie nodig hebt.

*Advies: Houd het `systeem`-fragment leverancier en product agnostisch. Een afdeling of domein zou bijvoorbeeld wel kunnen.*

**Centraal register URN naar URL**

Je kan er voor kiezen om een centrale “mapping” te maken en beschikbaar te stellen, binnen je organisatie, of zelfs landelijk. Dit is echter niet perse nodig en client applicatie zullen ten alle tijde deze informatie toch ook moeten opslaan omdat ze credentials nodig hebben.

*Advies: Gebruik in eerste instantie enkel de client applicatie configuratie en kijk later of er behoefte is aan een centraal register.*

**URLs die verwijzen naar binnen en buiten**

URLs worden nu gebruikt voor verwijzingen naar binnen de API (bijvoorbeeld een ZAAK met een STATUS) en voor verwijzingen naar buiten de API (bijvoorbeeld een ZAAK en een ZAAKTYPE).

Een client applicatie weet hoe het moet omgaan met een API als geheel. Verwijzingen naar binnen behoeven ook geen andere credentials dan die nodig waren voor het initiële object. Het gebruik van URLs is daarom niet nodig voor verwijzingen binnen dezelfde API. Het gebruik van URNs is dat om dezelfde reden ook niet. Enkel het`identifier`-fragment zou genoeg moeten zijn. Hieronder bijvoorbeeld voor `status` bij een ZAAK:

```json
{
  "urn": "utrecht:zaak:open-zaak-commutr:b67d13",
  "uuid": "b67d13",
  "zaakidentificatie": "ZAAK-0001",
  "zaaktype": "utrecht:zrc:zaaktype:open-zaak-commutr:60aa32",
  "status": "a431da",
  ...
}
```

*Advies: Gebruik in eerste instantie URNs enkel voor verwijzingen naar buiten en kijk later of URLs in zijn geheel weg kunnen voor interne verwijzingen.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dienstverleningsplatform.gitbook.io/platform-generieke-dienstverlening-public/onderzoeken/gebruik-en-migratie-van-urls-naar-urns.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
