- Created by Ann-Sofie Hildebrandt, last modified on Dec 02, 2025
Denne side beskriver hvordan du som anvender af Datafordeleren kan oprette forbindelse til at abonnere på hændelser for et givent register.
Der tages udgangspunkt i at abonnere på hændelser for et enkelt register, herunder BBR. Processen vil være den samme for registrene, registernavnet skal bare udskiftes til det register du ønsker at abonnere på hændelser for.
Sideinformation
| Forfatter | Datafordeleren |
|---|---|
| Oprettet | Nov 27, 2025 |
| Version | 1.0 |
| Ændret | Dec 02, 2025 |
| Sidehistorik |
Andre metoder til vedligeholdelse af kopiregister
Ønsker du ikke at bruge hændelser, kan du benytte deltadownloads der kommer én gang i døgnet, eller det ugentlige totaldownload. Hvilken metode du vælger at benytte til at vedligeholde dit kopiregister, kommer an på hvor hurtigt du som anvender har behov for at behandle den nye data.
Bemærk: Hændelser er det eneste måde hvor du som anvender eksplicit kan finde data der er blevet slettet, grundet at Datafordeleren ikke udstiller slettet data.
Hentning af totaldownloads er beskrevet i Eksempel på oprettelse samt vedligeholdelse af kopiregister for fildownload.
Forudsætninger og afgrænsninger
Følgende forudsætninger og afgrænsninger gælder for at kunne følge guiden:
- Denne guide antager at du som anvender har grundlæggende kendskab til hændelser, som kan findes under Entitetsbaserede hændelser. Her findes generel information om hændelser, brugsscenarier, samt beskrivelse af de data der er udstillet, hvad de betyder og hvordan de kan benyttes.
- Guiden omhandler kun hvordan tekniske hændelser kan hentes af anvendere. Med tekniske hændelser, menes der hændelser vedrørende opdateringer af registerdata. Denne guide indebærer ikke forretningshændelser, defineret ud fra registrenes egen forretningslogik.
- Du skal have oprettet en bruger på Datafordeler Administrationen. Se vejledning til dette på Brugeroprettelse Datafordeler Administration.
- Guiden forudsætter at et kopiregister allerede er oprettet, der afsnittet ”Etablering af kopiregister” i Eksempel på oprettelse samt vedligeholdelse af kopiregister for fildownload kan tages som udgangspunkt.
Sådan abonnerer du på hændelser
Ligesom entitetsbaserede GraphQL-tjenester, tilgås hændelser via et GraphQL-API. Hændelser tilgås på registerbasis og kræver at du benytter Datafordelerens autentifikation, det vil sige en OAuth hvis der er tale om et register med beskyttede registerdata og API-key til registre med ikke-beskyttede registerdata.
Opsætning med API-key er nærmere beskrevet API-Key, og opsætning med OAuth er nærmere beskrevet under Autentifikation og autorisation for GraphQL-tjenester.
Derudover bruger Datafordeleren i visse tilfælde en IP-allowlist til at verificere om klienten (dit eget IT-system) er autoriseret til at hente det efterspurgte data.
Når dit IT-system sender en forespørgsel til GraphQL-tjenesten med gyldig authentificering og adgang, returneres en stream som IT-systemet kan lytte på.
Efter 10 minutter bliver forbindelsen termineret, men en nye kan oprettes med det samme for at i praksis have en konstant forbindelse.
Eksempler på brug af tjenesten
Abonnering på hændelser ligner kald til de entitetsbaserede GraphQL-tjenester, dog med den forskel at forespørgsler der indsendes med et subscription præfix i stedet for query, og at der ikke er nogen paging grundet at en hændelse bliver returneret ad gangen.
Nedenstående eksempel kalder hændelser for BBR og efterspørger alle de tilgængelige kolonner for hændelsesdata.
subscription {
BBR_Events {
eventid
entityname
eventaction
fromfailedimport
datafordelerRegisterImportSequenceNumber
datafordelerOpdateringstid
object_id
object_datafordelerRowId
object_datafordelerRowVersion
object_status
object_registreringfra
object_registreringtil
object_virkningfra
object_virkningtil
}
}
Hændelser er udstillet på de samme URL’er som de entitetsbaserede tjenester, derfor kan oprettelse af abonnering på et register, i dette eksempel BBR, kaldes på følgende URL med en API-key som autentificering:
https://graphql.datafordeler.dk/BBR/v1?apiKey=xxxx |
Opsætning med Nitro til abonnering på hændelser
I dette eksempel er det valgt at bruge Nitro fra ChiliCream, da det har vist sig effektiv til at teste modtagelse af hændelser via SSE på GraphQL endepunkter. Andre værktøjer kan anvendes, men visse værktøjer som Postman har vist sig ikke at fungere optimalt til at modtage hændelser over SSE (Server Sent Events).
Denne metode giver mulighed for hurtigt at danne overblik over hvordan hændelser fungerer og hvilke data de indeholder, uden at skulle kode noget selv. Dette skal betragtes som en introduktion til hændelser.
For bedste resultater anvendes et register som hyppigt indlæser pakker, f.eks. BBR. Eksempel på opsætning af Connection Settings til BBR i Nitro:

Herefter kan der laves forespørgsler til BBR, med eksemplet fra forrige sektion, samt URL’et BBR’s endepunkt for entitetsbaserede tjenester.
Projektsetup
Dette afsnit gennemgår den tekniske opsætning af et udviklingsprojekt, der kan abonnere på og håndtere hændelser fra Datafordeleren. Afsnittet viser hvordan abonnementet, der demonstreres ovenfor, kan implementeres i en klient. Eksemplet tager udgangspunkt i et C# Console Application, men principperne kan overføres til andre programmeringssprog og projekttyper.
For at følge eksemplet skal følgende være installeret:
- .NET 8.0
- Visual Studio, Visual Studio Code eller lignende IDE
Adgang til NuGet Package Manager
NuGet pakker
Følgende Microsoft NuGet pakker, som er Microsofts officielle biblioteker til konfigurationshåndtering, skal tilføjes til projektet. Disse pakker medfølger ikke automatisk ved opsætning af et nyt Console App projekt og skal installeres ved hjælp af NuGet Package Manager Console:
- Install-Package Microsoft.Extensions.Configuration.Json
- Install-Package Microsoft.Extensions.Configuration.FileExtensions
Appsettings
Opret en appsettings.json fil som indeholder Client ID og Client Secret, der fås ved at følge afsnittet om Shared Secrets under Autentificeringsmetoder på Datafordeler Administration.
Et eksempel kan være dette:

Sørg for appsettings-filen er med i build ved at tilføje følgende til .csproj:

Filen er i eksemplet placeret følgende sted:

Adgang til Datafordelerens API
For at kunne tilgå Datafordelerens API, skal der hentes en access token. Først oprettes der en metode til at hente access token ud fra Client ID og Client Secret.
Denne kontakter https://auth.datafordeler.dk/realms/distribution/protocol/openid-connect/token som er endpointet der bruges til at hente access token.
Her er der sat op således at der bruges en ConfigurationBuilder til at hente fra appsettings.json, hvorefter ens access token returneres, og derefter kan bruges til at gennemføre opfølgende kald.
Bemærk at følgende blot er et eksempel på hvordan det kan implementeres.


Abonnement på hændelser
Efter at have hentet en access token som beskrevet forrige afsnit, kan man nu bruge denne til at abonnere på hændelser for et givent register. I dette eksempel bruges BBR. Forespørgslen som sendes afsted i variablen ”GraphQlQuery” og URL’et vil være de samme værdier som bruges under Eksempler pa brug af tjenesten.
Ved kald til BBR endepunktet med subscription forespørgslen, returneres en stream som lytter efter nye hændelser for registeret. Kommer der nye hændelser, vil disse blive tilføjet til en tæller og printet i konsollen. Til sidst printes det totale antal hændelser til konsollen.
I praksis ville man typisk processere dataen i hændelserne man modtager, afhængigt af hvilken funktion ens IT-system har. F.eks. ville man lave yderligere kald til BBR registeret for at få de data som hændelserne berør, eller processere hændelserne til at opdatere sin database.
Dette er blot et eksempel på hvordan en klient der abonnerer på hændelser kan implementeres. Hvad der sker med hændelserne bagefter, kommer meget an på hvad anvender IT-systemets funktion er.
Vedligeholdelse af kopiregister med hændelser kommer med et eksempel på dette.
Kodeeksempel for at kalde BBR og oprette en forbindelse
Kodeeksempel for GraphQL-request klasse der bruges i eksempel over for
Variabler brugt i øvrige kodeeksempler
Hændelsesdata
Når en hændelse modtages fra et register, i dette eksempel BBR, vil indholdet ligne nedenstående. En forklaring på hvad felterne betyder findes på Entitetsbaserede hændelser på Datafordeleren.
Disse data kan bruges til at lave en ny query, der henter objektet fra hændelsen via registerets GraphQL-tjeneste.
{
"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"
}
}
}
Vedligeholdelse af kopiregister med hændelser
Når dit system modtager hændelser som vist i Abonnement på Hændelser, indeholder disse kun metadata om ændringerne - ikke de faktiske registerdata. For at vedligeholde dit kopiregister kan du implementere opfølgende queries, der henter de komplette data for de objekter som hændelserne refererer til.
Dette kapitel viser hvordan du kan udvide kodeeksemplet fra Abonnement på Hændelser til at generere og udføre GraphQL-queries baseret på de modtagne hændelser.
Opfølgende queries på hændelser
For at holde den totaldownloadede entitet opdateret, skal der laves opfølgende kald på de hændelser der modtages. Her tages der udgangspunkt i hændelse der gives som eksempel fra Hændelsesdata. Dens data kan bruges til at fremsøge den specifikke række via. BBR’s GraphQL-tjeneste, ved at bruge feltet object_datafordelerRowId, som svarer til det tilsvarenede felt datafordelerRowId, der udstilles på GraphQL entiteten BBR_Bygning, hvilket ses på entitiyname.
Nedenstående query kan f.eks. bruges som opfølgende query mod BBR’s GraphQL-tjeneste. Udover at filtrere på datafordelerRowId bruges datafordelerRowVersion, som også findes i metadataen på en hændelse, for at være sikker på det er den korrekte version af dataen der sendes en forespørgsel på.
Har man behov for at finde data for flere hændelser i samme kald, kan man med fordel batche dem i et kald med en IN operator på datafordelerRowId.
Bemærk
Grundet at CPR udstilles gennem Custom tjenester, så er det denne der skal laves en forespørgsel mod, og ikke nogen speciel entitet.
Hændelser for CPR uddybes under Entitetsbaserede hændelser
query {
BBR_Bygning(
where: {
and: [
{ datafordelerRowId: { eq: "3b1040ef-ca52-4cb4-9788-909102a44155" } }
{ datafordelerRowVersion: { eq: 2 } }
]
}
) {
pageInfo {
endCursor
hasNextPage
}
nodes {
husnummer
id_lokalId
registreringFra
registreringTil
status
virkningFra
virkningTil
datafordelerRowId
datafordelerRowVersion
}
}
}
Processering af hændelser
Anvender IT-systemet fra Abonnement på hændelser kan omskrives til at håndtere events og generere den opfølgende query fra Opfølgende queries på hændelser.
Alternativt udstilles datafordelerRegisterImportSequenceNumber, datafordelerRowId og datafordelerRowVersion også med fildownloads, se Fildownload på Datafordeleren. Dette gør det muligt at direkte mappe hændelser til dit kopiregister data, når hændelser processeres, beroende på hvad anvender IT-systemets funktion er.
IT-systemet deserialiserer hændelsen, og kalder videre til at processere den
IT-systemet processerer hændelsen, tjekker at det er et insert på EventAction, laver et opfølgende kald og gemmer entiteten i databasen
Kodeeksempel på klasser til at processere hændelse
Alternativ til abonnering
Hvis man vil hente data mere sjældent, kan GraphQL queries benyttes i stedet for at abonnere på hændelser. Se Entitetsbaserede hændelser for mere information for GraphQL queries for hændelser. EventID for hændelser kan bruges for at filtrere på nye hændelser, hvilket giver dette flow:

Med denne opsætning er det op til anvenderen at bestemme hvornår nye hændelser skal hentes og processeres. Bemærk at queries for hændelser, i modsætning til abonnering, har paginering og returnerer flere hændelser. Queries tillader også anvender at hente historiske hændelser. En query for nye BBR-hændelser, der det sidste kendte Event ID er 36, kan f.eks. være:
query {
BBR_Events(where: { eventid: { gt: 36 } }) {
nodes {
object_datafordelerRowId
entityname
eventaction
eventid
}
}
}
Resterende proces er ens med den for abonnering, der er beskrevet i dette dokument. F.eks. kan en opfølgende query for den relevante entitet laves med de object_datafordelerRowId der er returneret for at hente den nye data.
Opsummering
Efter at have fulgt trinene i denne guide, har du nu implementeret en komplet løsning til at abonnere på og håndtere hændelser fra Datafordeleren. Din implementering omfatter følgende funktionalitet i rækkefølge:
- Projektstruktur: Dit C#-projekt er korrekt opsat med nødvendige NuGet-pakker (Microsoft.Extensions.Configuration, Npgsql) og konfigurationsfiler (appsettings.json).
- Autentificering: Du har implementeret programmatisk hentning af access tokens til sikker kommunikation med Datafordelerens API'er.
- Hændelsesabonnement: Din applikation kan nu abonnere på tekniske hændelser for specifikke registre (f.eks. BBR) via GraphQL subscriptions og modtage nær realtidsdata.
- Hændelsesbehandling: Systemet lytter aktivt på nye hændelser og kan deserialisere modtagne hændelsesdata med information om entitetsnavne, handlingstyper og objektidentifikatorer.
- Opfølgende queries: Du har implementeret funktionalitet til at generere og udføre opfølgende GraphQL-queries baseret på hændelsesdata.
- Kopiregister-vedligeholdelse: Din løsning kan nu vedligeholde et lokalt kopiregister i realtid ved at kombinere totaldownloads med hændelsesbaserede opdateringer.