Versions Compared
Key
- This line was added.
- This line was removed.
- Formatting was changed.
...
Nu
...
hvor
...
du
...
har
...
fået
...
overblik
...
over,
...
hvad
...
hændelser
...
er
...
og
...
hvilke
...
brugsscenarier
...
de
...
dækker,
...
er
...
næste
...
skridt
...
at
...
forstå,
...
hvordan
...
du
...
konkret
...
implementerer
...
og
...
anvender
...
hændelser
...
i
...
din
...
løsning.
...
Denne side guider dig gennem de praktiske aspekter af at arbejde med hændelser på Datafordeleren. Derudover, som supplement til denne guide findes Eksempel på vedligeholdelse af kopiregister med hændelser, der indeholder kodeeksempler på hvordan du vedligeholder dit eget kopiregister med hændelser.
Som tidligere beskrevet, findes der to primære tilgange til at anvende hændelser, afhængigt af dine specifikke behov:
- Query-baseret tilgang - Velegnet når du ønsker at hente hændelser på forespørgsel, fx som del af en planlagt synkroniseringsproces eller når realtidsopdateringer ikke er kritiske.
- Abonnement-baseret tilgang - Optimal når du har behov for næsten realtidsnotifikationer om dataændringer, fx til at udløse automatiske processer eller holde kritiske systemer opdateret.
Hvordan begge tilgange implementeres i en anvenders it-system eller via klient software, vises i Eksempel på vedligeholdelse af kopiregister med hændelser. Her findes der forskellige kodeeksempler og en vejledning til hvordan det kan implementeres i et .NET-projekt med C#.
I de følgende afsnit gennemgår vi begge tilgange med konkrete eksempler på hvordan hændelser kan kaldes på Datafordeleren, og bedste praksis.
| Table of Contents |
|---|
Sideinformation
| Display Metadata | ||
|---|---|---|
|
Autorisation for hændelser
Autorisation for hændelser sker på entitetsniveau ("entityname" i GraphQL), hvilket betyder at adgang kontrolleres baseret på de specifikke entiteter du som anvender forsøger at tilgå.
For eksempel er det muligt med adgang til "Ejendomsadministrator"-entiteten i EJF at filtrere på og modtage hændelser for denne entitet med nedenstående query
| Code Block |
|---|
query { EJF_Events(where: { entityname: { eq: "Ejendomsadministrator" |
...
} |
...
}) |
...
{
|
...
nodes |
...
{ |
...
entityname |
...
}
|
...
}
|
...
} |
Dog er det ikke muligt for at modtage data for en anden entitet i EJF, for eksempel "Ejerskab" som det ses nedenfor, hvis du ikke har adgang til specifikt den entitet.
| Code Block |
|---|
query {
EJF_Events(where: { entityname: { eq: "Ejerskab" } }) {
nodes {
entityname
}
}
} |
For vejledning og dybdegående forklaring af autentifikation og autorisation til hændelser, se Autentifikation og autorisation for GraphQL-tjenester. Denne vejledning gennemgår detaljeret hvordan hver metode implementeres, herunder oprettelse af credentials, håndtering af Access Tokens, IP-begrænsninger for adgangsbegrænset data, samt praktiske eksempler på opsætning i Postman. Derudover beskrives det hvordan OAuth-flow fungerer med både shared secrets og certifikater, inklusiv token-validitet og sikkerhedsovervejelser.
Autorisation for CPR-hændelser
CPR udstilles med Custom tjenester og giver ikke adgang til sine entiteter som andre register (undtaget CprHændelseskode). Dette påvirker hvordan hændelser tilgås for CPR, hvor dette gælder for deres entiteter:
- AdministrativEnhed og AdministrativEnhedType er ikke beskyttet og hændelser for disse kan tilgås af alle anvendere
- CustomPrivateSectorPerson giver IKKE adgang til nogle hændelser
- CustomPublicSectorPerson giver adgang til hændelser for alle beskyttede entiteter
- CprHændelseskode hændelser kan tilgås ved godkendt dataadgang
CPR godkender ikke adgang til nogen anden entitet end dem ovenfor. Hvis du vil tilgå hændelser for beskyttede entiteter, skal du altså have CustomPublicSectorPerson dataadgang, eller CprHændelseskode adgang, hvis du kun er interesseret i denne entitet.
| Info |
|---|
Bemærk |
...
CustomPublicSectorPerson giver også adgang til at kunne se hændelser for CprHændelsekode, men ikke til at kunne lave generelle queries |
...
til CprHændelsekode entiteten. |
Mulige filtreringer
Filtreringsmuligheder varierer for GraphQL-entiteterne. Hændelser er ens for alle registre, med undtagelse af CPR-registeret der indeholder ekstra felter, som tidligere nævnt i afsnit
...
...
.
...
...
Hændelser
GraphQL-tjenesterne understøtter filtreringsmuligheder på hændelser, både på hændelsesspecifikke felter og dataobjektrelaterede felter. Alle filtre kan kombineres ved hjælp af "and"-operatoren for at skabe avancerede forespørgsler.
Specifikationerne kan findes i GraphQL-skemaet for hvert register der udstiller hændelser, under {registernavn}_EventsFilterInput. For eksempel for BBR vil det findes under BBR_EventsFilterInput.
Tilladte operatorer
...
Filtreringsoperatorerne
...
følger
...
samme
...
principper
...
som
...
beskrevet
...
i Transition mellem REST-services og GraphQL-services.pdf (OBS engelsk vejledning), i afsnittet "Analyse filters". Her findes der eksempler på mere komplekse filtreringsscenarier. Nedenstående tabel viser de specifikke operatorer tilgængelige for hændelser.
Feltnavn | Datatype | Understøttede operatorer | Begrænsninger |
datafordelerOpdateringstid | DateTime | eq, gt, gte, lt, lte | - |
datafordelerRegisterImportSequenceNumber | Int | eq, gt, gte, lt, lte, in | MinValue: 1, MaxListSize: 100 |
entityname | String | eq, in | MinLength: 1, MaxLength: 3999, MaxListSize: 100 |
eventaction | String | eq, in | Kun tilladt: "i", "u", "d", MaxListSize: 100 |
eventid | Long | eq, gt, gte, lt, lte, in | MinValue: 1, MaxListSize: 100 |
object_id | String | eq, in | MinLength: 1, MaxLength: 3999, MaxListSize: 100 |
object_status | String | eq, in | MinLength: 1, MaxLength |
...
: 3999, MaxListSize: 100 |
Yderligere bemærkninger:
- Numeriske felter med MinValue-begrænsning skal være >= den angivne værdi
CPR-felter
...
CPR-registeret
...
indeholder
...
to
...
yderligere
...
felter
...
i
...
hændelserne,
...
som
...
kan
...
bruges
...
til
...
filtrering
...
på
...
kommunetilhørsforhold.
...
Disse
...
vises nedenfor. Bemærk,
...
at
...
disse
...
felter
...
hentes
...
fra
...
CprHændelse-entiteten,
...
og
...
er
...
altså
...
"null"
...
for
...
alle
...
hændelser
...
hvor
...
"entityname"
...
ikke
...
er
...
"Cprhaendelse".
...
CprHændelse
...
indeholder
...
også
...
de
...
hændelser
...
som
...
CPR
...
klassificerer
...
som
...
en
...
hændelse.
...
På
...
grund
...
af
...
dette
...
er
...
det
...
en
...
anbefaling,
...
at
...
man
...
altid
...
filtrerer
...
hændelser
...
for
...
denne
...
entitet
...
,
...
hvis
...
man
...
vil
...
tilgå
...
beskyttet
...
data
...
(se
...
...
...
...
),
...
eller
...
har
...
behov
...
af
...
at
...
filtrere
...
med
...
kommunekode.
...
Se Eksempel på filtrering af kommunekode i CPR for eksempel. Det object_id der udstilles gennem hændelser kan derefter bruges som input i CprPublicSector-tjenesten for at hente den nye data. Se GraphQL på Datafordeleren for mere information om CPRs custom tjenester.
Feltnavn | Datatype | Understøttede operatorer | Begrænsninger |
object_kommunekodetidligere | String | eq, in | MaxLength: 3999 MaxListSize: 100 |
object_kommunekodenuvaerende | String | eq, in | MaxLength: 3999 MaxListSize: 100 |
...
Eksempel på filtrering af hændelser
...
Eksempel på filtrering af kommunekode i CPR
Eksemplet
...
nedenfor viser filtrering på begge kommunekode-felter for hændelser på Personer i CPR-registeret.
| Code Block |
|---|
where: { |
...
entityname: { eq: "Cprhaendelse" } |
...
object_kommunekodetidligere: { eq: "0461" } |
...
object_kommunekodenuvaerende: { eq: "0101" } |
...
} |
...
...
Eksempel på filtrering i BBR
...
Nedenfor er et eksempel på en query med filtrering af hændelser mod BBR-registeret.
...
| Code Block |
|---|
query |
...
{
BBR_Events(
where: |
...
{
and: |
...
[
|
...
{ eventaction: |
...
{ eq: "i" |
...
} |
...
}
|
...
{ datafordelerOpdateringstid: |
...
{ gte: "2025-01-01T00:00:00Z" |
...
} |
...
}
|
...
{ entityname: |
...
{ eq: "Bygning" |
...
} |
...
}
|
...
{ object_status: |
...
{ eq: "Aktiv" |
...
} |
...
}
|
...
]
|
...
}
first: 100
) |
...
{
nodes |
...
{
eventid
eventaction
entityname
object_id
object_status |
...
|
...
datafordelerOpdateringstid } |
...
pageInfo { |
...
|
...
|
...
|
...
hasNextPage
endCursor
}
}
} |
Optimeringsstrategier
Effektiv filtrering er afgørende for både performance og ressourceforbrug når du arbejder med hændelser på Datafordeleren. Ved at anvende præcise filtreringsparametre kan du betydeligt reducere den datamængde der overføres og processeres, hvilket resulterer i:
- Reduceret netværkstrafik da kun relevante hændelser sendes over netværket
- Hurtigere responstider da mindre datasæt processeres hurtigere af både server og klient
- Lavere ressourceforbrug da der vil være mindre CPU- og hukommelsesbelastning i dit system
...
RegisterImportStatus
DAF_RegisterImportStatus entiteten har ingen filtreringsmuligheder, og tilgås uden filtrering som querien fra eksemplet
...
...
viser.
...
Send query
...
Ved
...
afsendelse
...
af
...
queries
...
fungerer
...
hændelser
...
på
...
samme
...
| Wiki Markup |
|---|
Oprettelse af abonnementer til hændelser vil ligne almindelige queries på forespørgselsniveau. Kodeeksempler på at implementere forespørgslerne i en klient kan findes i *\[C{*}<span style="color: #0f2147"><strong>0200-HAENDELSE-KOPIREGISTER]</strong></span>. |
...
måde
...
som de entitetsbaserede tjenester, derfor kan GraphQL på Datafordeleren bruges som vejledning til hvordan queries sendes afsted.
Opret abonnement
Oprettelse af abonnementer til hændelser vil ligne almindelige queries på forespørgselsniveau. Kodeeksempler på at implementere forespørgslerne i en klient kan findes i Eksempel på vedligeholdelse af kopiregister med hændelser.
Retursvar
Når en klient har oprettet forbindelse til at abonnere på hændelser for et register, vil dataene som en hændelse indeholder i retursvaret, ligner
...
følgende eksempel der kommer fra BBR.
| Code Block |
|---|
{"data": |
...
{"BBR_Events": |
...
{ "datafordelerOpdateringstid":"2025-06-24T13:46:02.424335Z", |
...
"datafordelerRegisterImportSequenceNumber":99999999, |
...
"entityname":"Bygning", |
...
"eventaction":"i", |
...
"eventid":1177475, |
...
"object_datafordelerRowId":"3b1040ef-ca52-4cb4-9788-909102a44155", |
...
"object_datafordelerRowVersion":1, |
...
"object_id":"49b2aafe-5fb4-42b5-b22d-7104a616804f", |
...
"object_registreringfra":"2025-06-24T13:46:02.424335Z", |
...
"object_ |
...
registreringtil":"2025-06-24T13:46:02.424335Z", |
...
"object_status":"6", "object_ |
...
virkningfra":"2025-06-24T13:46:02.424335Z" |
...
,
"object_virkningtil":"2025-06-24T13:46:02.424335Z"
}
}
} |
Specielle fejlmeddelelser
Hændelser og Register Import Status kan returnere unikke fejlmeddelelser i GraphQL, der ikke findes for andre entiteter. Se nedenstående for et eksempel.
| Code Block |
|---|
{
"errors": |
...
[
|
...
{
"message": "eventaction filtered value is not valid. It only allows the following values: i, u, d",
"locations": |
...
[
|
...
{
"line": 2,
"column": 42
|
...
}
|
...
],
"path": |
...
[
"MAT_Events"
|
...
],
"extensions": |
...
{
"traceId": "00-8d74c84ec80437d8a0ad3d716bc7b6da-e19e2140e0a1d526-01",
"code": "DAF-GQL-0016"
|
...
}
|
...
}
|
...
],
"data" |
...
: {
"MAT_Events": null
}
} |
Tabellen nedenfor beskriver alle specielle fejlmeddelelser der kan returneres i GraphQL for Register Import Status og Hændelser, og hvordan disse kan håndteres:
Beskrivelse | Code | Løsning | Entitet |
Ikke tilladt filtrering, f.eks. filtrering på eventaction med en værdi der ikke er i, u eller d. Se |
...
ovenstående for et eksempel | DAF-GQL-0016 | Fejlmeddelelsen indeholder de værdier der er tilladt. Opdatere filter i din query til at være indenfor disse grænseværdier | Hændelser |
Manglende adgang, eller ukendt navn for den filtrerede entitet | DAF-GQL-0016 | Tjek filter for "entityname" i din query. Sikre at du har adgang og at navn er for en rigtig entitet (case sensitive) | Hændelser |
Ingen tilgængelig import status for registret | DAF-GQL-0023 | Registret har ikke indlæst data efter udstilling af moderniserede hændelser. Prøv igen senere for at hente status | Register Import Status |
...