WEM Endpoint
Het WEM endpoint geeft in één call de volledige bibliografische hiërarchie terug voor een manifestatie: het Werk, de Expressie en de Manifestatie met alle relaties resolved.
Interactieve documentatie
Bekijk dit endpoint ook in de API Reference voor een interactieve try-out met Scalar.
Wat is het WEMI model?
Open Vlacc gebruikt het FRBR/WEMI model om bibliografische records te structureren:
| Niveau | Beschrijving | Voorbeeld |
|---|---|---|
| Work | Het intellectuele concept | "Harry Potter en de Steen der Wijzen" (het verhaal) |
| Expression | Een specifieke realisatie | De Nederlandstalige vertaling |
| Manifestation | Een fysieke publicatie | De paperback-editie, ISBN 978-... |
Het WEM endpoint navigeert automatisch van manifestatie naar expressie naar werk en resolved alle relaties op elk niveau. Hierdoor hoef je als consumer maar één call te doen in plaats van drie afzonderlijke entity-requests met handmatige relatie-opvolging.
Request
GET /entities/wem/{manifestation_id}| Parameter | Type | Verplicht | Beschrijving |
|---|---|---|---|
manifestation_id | string (path) | Ja | Het ID van de manifestatie (bijv. M-RAMQ659KX3) |
Voorbeeld
curl -X GET \
"__API_BASE_URL__/entities/wem/M-RAMQ659KX3" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/json"Response structuur
De response bevat drie objecten op het hoogste niveau:
{
"work": { ... },
"expression": { ... },
"manifestation": { ... }
}Elk object heeft dezelfde structuur:
| Veld | Type | Beschrijving |
|---|---|---|
type | string | Entity type (bijv. work_word, expression_word, manifestation_word) |
metadata | object | Metadata als key-value dictionary |
relations | object | Relaties als dictionary, gekeyed op het ID van de gerelateerde entiteit |
Metadata
Metadata wordt geretourneerd als een dictionary gekeyed op veldnaam. Elke waarde is een object met minstens een value property:
{
"metadata": {
"title": { "value": "Mijn doodgeboren kindje" },
"isbn": { "value": "9789025909963" },
"year_of_publication": { "value": "2024" }
}
}Relaties
Relaties worden geretourneerd als een dictionary gekeyed op het ID van de gerelateerde entiteit. Elke relatie bevat het type, een label en resolved velden afhankelijk van het entity type:
{
"relations": {
"TAAL-dut": {
"type": "refLanguages",
"label": "language",
"value": "Nederlands",
"code": "dut"
},
"PERS-123": {
"type": "refAuthors",
"label": "person",
"value": "Wagenmakers, Harm",
"life_dates": "1980-"
}
}
}Resolved relatietypes
Het endpoint resolved alle relaties en voegt de relevante metadata toe. Welke velden aanwezig zijn hangt af van het type gerelateerde entiteit:
| Entity type | Velden | Beschrijving |
|---|---|---|
language | value, code | Taal naam + ISO-code |
person | value, life_dates | Naam + levensjaren |
corporation | value | Naam van de organisatie |
subject | value | Onderwerp (label = "nomen", zie onder) |
publisher | value | Naam van de uitgever |
target_audience | value | Doelgroep |
genre | value | Genre |
place | value | Plaatsnaam |
time | value | Tijdsperiode |
title | value, subtitle | Titel + ondertitel |
siso | code, land_or_language | SISO-classificatie + land/taal |
code_wording | code, wording, code_wording_type | Functieaanduiding (bijv. auteur, illustrator) |
zizo | code, title, levels | ZIZO-classificatie met hiërarchie |
Het label veld
Elke resolved relatie bevat een label veld:
- Voor subjects is het label altijd
"nomen"(conform de catalogiseringstandaard) - Voor alle andere types is het label gelijk aan het entity type (bijv.
"person","language")
ZIZO hiërarchie
ZIZO (Zelfstandig Inhoudelijk Zoeken) is een classificatiesysteem voor openbare bibliotheken. Het WEM endpoint resolved niet alleen de ZIZO-code, maar ook de volledige hiërarchie van breed naar specifiek.
Voorbeeld ZIZO relatie
{
"ZIZO-456": {
"type": "refZizos",
"label": "zizo",
"code": ["OKZWZV"],
"title": "Zwangerschapsverlies",
"levels": [
{ "level": "1", "title": "Volwassenen ZIZO" },
{ "level": "2", "title": "Ouders - kinderen" },
{ "level": "3", "title": "Zwangerschapsverlies" }
]
}
}Het levels array bevat de volledige hiërarchie gesorteerd van breed (level 1) naar specifiek. Dit is handig voor het tonen van broodkruimels of het filteren op hogere niveaus.
Code voorbeelden
Python
import requests
BASE_URL = "__API_BASE_URL__"
TOKEN = "your_access_token"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Accept": "application/json"
}
# Haal WEM data op voor een manifestatie
response = requests.get(
f"{BASE_URL}/entities/wem/M-RAMQ659KX3",
headers=headers
)
wem = response.json()
# Werk-niveau informatie
work = wem["work"]
print(f"Type: {work['type']}")
# Toon alle auteurs van het werk
for rel_id, rel in work["relations"].items():
if rel["type"] == "refAuthors":
print(f"Auteur: {rel['value']}")
if "life_dates" in rel:
print(f" Levensjaren: {rel['life_dates']}")
# Manifestatie metadata
manifestation = wem["manifestation"]
if "isbn" in manifestation["metadata"]:
print(f"ISBN: {manifestation['metadata']['isbn']['value']}")JavaScript
const BASE_URL = '__API_BASE_URL__';
const TOKEN = 'your_access_token';
async function getWemData(manifestationId) {
const response = await fetch(
`${BASE_URL}/entities/wem/${manifestationId}`,
{
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Accept': 'application/json'
}
}
);
return response.json();
}
// Gebruik
const wem = await getWemData('M-RAMQ659KX3');
// Toegang tot de drie niveaus
const { work, expression, manifestation } = wem;
// Alle talen van de expressie
const languages = Object.values(expression.relations)
.filter(rel => rel.type === 'refLanguages')
.map(rel => ({ name: rel.value, code: rel.code }));
console.log('Talen:', languages);
// ZIZO classificatie van het werk
const zizos = Object.values(work.relations)
.filter(rel => rel.type === 'refZizos');
for (const zizo of zizos) {
console.log(`ZIZO: ${zizo.title}`);
console.log('Hiërarchie:', zizo.levels.map(l => l.title).join(' > '));
}Recent aangemaakte of bewerkte manifestaties ophalen
Als je vertrekt vanuit manifestaties en steeds de meest recente wijzigingen wilt ophalen (bijv. voor een synchronisatie met een extern systeem), kun je de bestaande endpoints combineren met het WEM endpoint.
Stap 1: Recent gewijzigde manifestaties opvragen
Eenvoudig — GET /entities met sortering:
curl -X GET \
"__API_BASE_URL__/entities?type=manifestation&order_by=date_updated&asc=0&limit=50" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Dit geeft de 50 meest recent bewerkte manifestaties, gesorteerd van nieuwst naar oudst.
| Parameter | Waarde | Beschrijving |
|---|---|---|
type | manifestation | Alleen manifestaties |
order_by | date_updated | Sorteer op laatste wijzigingsdatum |
asc | 0 | Aflopend (nieuwste eerst) |
limit | 50 | Aantal resultaten |
skip | 0 | Paginering offset |
Sorteer op date_created voor nieuwe records
Gebruik order_by=date_created als je alleen nieuw aangemaakte manifestaties wilt, in plaats van recent bewerkte.
Geavanceerd — POST /entities/filter met datumbereik:
Voor een periodieke sync is het handiger om te filteren op manifestaties die gewijzigd zijn sinds je laatste sync-moment:
curl -X POST \
"__API_BASE_URL__/entities/filter?order_by=date_updated&asc=0&limit=100" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"type": "selection",
"key": "type",
"value": [
"manifestation_map",
"manifestation_music",
"manifestation_serial",
"manifestation_footage",
"manifestation_mixed_material",
"manifestation_word",
"manifestation_computer_file"
],
"match_exact": true
}
]'Manifestatie types
Er zijn meerdere manifestatie-subtypes (manifestation_word, manifestation_music, etc.). Het filter endpoint werkt op het exacte type, dus je geeft alle gewenste subtypes mee in de value array.
Stap 2: WEM data ophalen per manifestatie
Loop vervolgens over de resultaten en haal per manifestatie de volledige WEMI-hiërarchie op:
# Uit de response van stap 1 haal je de _key van elke manifestatie
curl -X GET \
"__API_BASE_URL__/entities/wem/M-RAMQ659KX3" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Compleet voorbeeld: synchronisatie workflow
Python
import requests
BASE_URL = "__API_BASE_URL__"
TOKEN = "your_access_token"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Accept": "application/json",
"Content-Type": "application/json"
}
# Stap 1: Haal recent gewijzigde manifestaties op
response = requests.get(
f"{BASE_URL}/entities",
headers=headers,
params={
"type": "manifestation",
"order_by": "date_updated",
"asc": 0,
"limit": 50
}
)
manifestations = response.json()
# Stap 2: Haal WEM data op per manifestatie
for entity in manifestations:
manifestation_id = entity["_key"]
wem = requests.get(
f"{BASE_URL}/entities/wem/{manifestation_id}",
headers=headers
).json()
work = wem["work"]
expression = wem["expression"]
manifestation = wem["manifestation"]
print(f"Manifestatie: {manifestation_id}")
print(f" Werk type: {work['type']}")
for rel_id, rel in work["relations"].items():
if rel["type"] == "refAuthors":
print(f" Auteur: {rel['value']}")JavaScript
const BASE_URL = '__API_BASE_URL__';
const TOKEN = 'your_access_token';
const headers = {
'Authorization': `Bearer ${TOKEN}`,
'Accept': 'application/json'
};
// Stap 1: Recent gewijzigde manifestaties
const listResponse = await fetch(
`${BASE_URL}/entities?type=manifestation&order_by=date_updated&asc=0&limit=50`,
{ headers }
);
const manifestations = await listResponse.json();
// Stap 2: WEM data per manifestatie
for (const entity of manifestations) {
const wemResponse = await fetch(
`${BASE_URL}/entities/wem/${entity._key}`,
{ headers }
);
const wem = await wemResponse.json();
console.log(`Manifestatie: ${entity._key}`);
console.log(` Werk type: ${wem.work.type}`);
const auteurs = Object.values(wem.work.relations)
.filter(rel => rel.type === 'refAuthors')
.map(rel => rel.value);
console.log(` Auteurs: ${auteurs.join(', ')}`);
}Foutcodes
| Status | Beschrijving |
|---|---|
200 | Succes — WEM data teruggegeven |
401 | Unauthorized — ongeldige of ontbrekende Bearer token |
404 | Manifestatie niet gevonden |