Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Opdateret interne links

Denne transitionsguide beskriver forskelle mellem Datafordelerens nuværende hændelser og de moderniserede hændelser der udstilles i GraphQL-tjenesterne, samt hvordan du som anvender af de nuværende hændelser, kan komme i gang med at bruge de moderniserede hændelser der udstilles på GraphQL-tjenester.

Det skal bemærkes at moderniserede hændelser og de nuværende hændelser driftes parallelt i en periode, så anvendere af Datafordeleren har mulighed for at skifte fra REST-hændelser til GraphQL-hændelser.


Table of Contents

Sideinformation

Display Metadata
hidetableheadertrue



Datafordelerens nuværende hændelser


Datafordelerens nuværende hændelsessystem giver anvendere mulighed for at blive informeret om ændringer i registerdata gennem to forskellige leveringsmetoder. Afhængigt af teknisk behov og systemarkitektur kan anvendere vælge mellem PUSH-hændelser, hvor Datafordeleren automatisk sender notifikationer, eller PULL-hændelser, hvor anvender selv henter opdateringer efter behov. 

Læs om de nuværende hændelser på *\[NUDAF-HAENDELSE-DOKUMENTATION\]* og *\[NUDAF-HAENDELSE-GUIDE\]{*}på Hændelser på Datafordeleren og Guide til hændelser på Datafordeleren.






Ligheder med moderniserede hændelser


De nuværende hændelser kan relateres til moderne hændelser, da de har konceptuelle ligheder.

Queries kan sammenlignes med PULL-hændelser:

  • Anvender laver et API kald
  • Manuel forespørgsel
  • Enkelt request-response
  • Præcis specificering af ønskede data

Subscriptions kan sammenlignes med PUSH-hændelser:

  • Datafordeleren sender kontinuerlige beskeder
  • Beskeder sendes når data opdateres
  • Leverer én hændelse ad gangen






Fordele ved at skifte til moderne hændelser


Transitionen fra Datafordelerens nuværende hændelsessystem til de moderniserede hændelser bringer flere betydelige fordele for anvendere. Den mest markante forbedring ligger i den forbedrede tekniske arkitektur, hvor moderne hændelser anvender moderne, industrielle standarder som Server-Sent Events (SSE) i stedet for proprietær PUSH-løsninger. Dette sikrer et ensartet API-design, hvor alle hændelser følger samme GraphQL-skemastruktur, hvilket reducerer kompleksiteten i integration og giver mere robuste fejlmeddelelser gennem standardiserede HTTP-statuskoder.

Derudover, skal anvendere i det nuværende system anmode om PUSH-hændelser gennem en ofte langvarig proces, hvilket kan forsinke adgang til kritiske dataopdateringer. De moderniserede hændelser eliminerer denne barriere ved at tilbyde adgang gennem GraphQL-grænsefladen, såfremt anvender har de nødvendige adgange.

Moderne hændelser tilbyder også betydeligt øget fleksibilitet og præcision sammenlignet med det nuværende system. Anvendere får nu mulighed for:

  • Granulær filtrering på specifikke felter som eventaction, entityname og eventid
  • Præcis specificering af hvilke felter der ønskes returneret i hændelser gennem GraphQL queries
  • Kombinering af flere filtre ved hjælp af "and"-operator til målrettede forespørgsler

Fra et ydeevne- og skalerbarhedsperspektiv medfører moderne hændelser reduceret netværkstrafik, da kun relevante data returneres baseret på query-specifikationen.

Paging håndterer store datasæt mere effektivt, mens SSE-baserede abonnementer sikrer næsten øjeblikkelige notifikationer om dataændringer.






Hændelsesabonnementer og historiske data


I de nuværende hændelser kan et abonnement kun modtage hændelser, der sker efter oprettelsen af abonnementet. Det er ikke muligt at hente hændelser, som er indkommet til datafordeleren inden oprettelsen af abonnementet. I de moderniserede hændelser er det muligt at hente ældre hændelser ved at lave en GraphQL query med den startdato (datafordelerOpdateringstid) eller eventid, hvorfra hændelser ønskes modtaget.






Transition af filtrering


Filtreringsmulighederne i moderne hændelser adskiller sig markant fra de nuværende hændelser både i struktur og funktionalitet.






Oversigt over forskel mellem nuværende hændelsesfiltrering og GraphQL hændelsesfiltrering


Nedenfor ses en oversigt over forskellene mellem den nuværende hændelsesfiltrering og GraphQL hændelsesfiltrering.



Aspekt

Nuværende hændelsesfiltrering

GraphQL hændelsesfiltrering

Filterstruktur

  • Betingelser består af: Felt + Operator + Værdi
  • Gruppering med logiske operatorer (OG/ELLER)
  • Opsætning via webportal med grafisk interface
  • Defineret direkte i GraphQL query-syntaks
  • Kombinering kun med AND-operator
  • Programmatisk opsætning i kode

Tilgængelige felter

  • Beskedtype, BeskedansvarligAktør, TværgåendeProces
  • ObjektID, ObjektType, Registreringsaktør
  • Registreringstid, Status, RegistreringsID
  • Objekthandling, OpgaveEmne
  • RelateretObjektID, RelateretObjekttype
  • eventid, entityname, eventaction
  • datafordelerOpdateringstid, datafordelerRegisterImportSequenceNumber
  • object_id, object_datafordelerRowId, object_datafordelerRowVersion
  • object_registreringfra/til, object_virkningfra/til, object_status
  • CPR-specifikke: object_kommunekodeNuvaerende, object_kommunekodeTidligere

Operatorer

  • = (Lig med), <> (Ikke lig med)
  • <, <=, >, >= (Sammenligning)
  • I, IKKE I (Liste-medlemskab)
  • INDEHOLDER (kun for Objekthandling)
  • eq (equals), in (liste-medlemskab)
  • gt, gte, lt, lte (sammenligning)
  • Ingen negation eller "indeholder" operatorer






Praktisk transition


Tabellen nedenfor viser nuværende felter og deres GraphQL-ækvivalent, hvilket kan bruges til at oversætte hændelser, der hentes via REST, til queries der kan hentes moderne hændelser med.



Nuværende felter

GraphQL-ækvivalent

ObjektType

entityname

Objekthandling

eventaction

Registreringstid

object_registreringfra / object_registreringtil

ObjektID

object_id

Status

object_status

Info

Bemærk

Objekthandling og eventaction har ikke fuldstændig samme betydning. I REST-hændelserne kunne registrene frit definere Objekthandling, som derfor ikke nødvendigvis stemte overens med de faktiske databaseoperationer. For eksempel kunne en forretningslogisk "opdatering" af en person godt resultere i en INSERT-operation i databasen, men stadig have Objekthandling sat til "Update".

I moderniserede hændelser bliver eventaction derimod defineret ud fra den faktiske databaseoperation (INSERT/UPDATE/DELETE) der er foretaget. Dette betyder, at alt efter hvordan et register vælger at opdatere data med indlæsningspakker, for eksempel, hvis registeret laver INSERT operationer i stedet for UPDATE operationer, kan det resultere i at anvendere er nødt til at lave yderligere kald til den pågældende entitet for at tjekke hvordan de potentielt flere rækker ser ud for et bestemt ObjektID.




Eksempler på filtrering


Følgende eksempler viser hvordan almindelige filtreringsscenarier fra de nuværende hændelser kan oversættes til GraphQL-syntaks. Eksemplerne er organiseret efter filtreringstype og viser både den nuværende betingelsesstruktur og den tilsvarende GraphQL-implementering.

Eksemplerne kan bruges som reference ved migrering fra nuværende til moderniserede hændelser, og tager udgangspunkt i BBR. For hver filtreringstype vises først betingelsen som den opsættes i det nuværende system, efterfulgt af den ækvivalente GraphQL query.




Entitetsbaseret-filtrering


  • Betingelse: ObjektType = "Bygning"


Code Block
where: { entityname: { eq: "Bygning" } }




Handlingsbaseret-filtrering


  • Betingelse: Objekthandling = "Create"


Code Block
where: { eventaction: { eq: "i" } }




Kombineret filtrering


  • Betingelse: ObjektType = "Bygning"
  • Betingelse: Objekthandling = "Create,Update"


Code Block
where: {
entityname: { eq: "Bygning" }
eventaction: { in: ["i", "u"] }
}






Eksempel på transition til moderniserede hændelser


Afsnittet giver et eksempel på hvordan en eksisterende anvender på Datafordeleren kan overgå fra at bruge PUSH- og PULL-hændelser, til at bruge moderniserede hændelser. Eksemplerne her i transitionsguiden tager udgangspunkt i en anvender som ønsker hændelser for entiteten BBR_Bygning fra BBR-registeret.






PULL-hændelser


Her henter anvenderen hændelsesbeskeder ved at kalde Datafordeleren, svarende til abonnering på hændelser beskrevet i afsnit 2.3.2 (Abonnement på hændelser). Afsnittet  Afsnittet påbegyndes med en situationsbeskrivelse, efterfulgt af konkrete trin der beskriver transitionen.




Situationsbeskrivelse


Anvenderen har været inde og foretage filtrering på de hændelser, som Datafordeleren returnerer (se afsnittet om filtrering på *\[NUDAF-HAENDELSE-GUIDE\]{*} Guide til hændelser på Datafordeleren). Filtrering er sat op så der kun returneres hændelser for BBR_Bygning.
Anvenderen benytter følgende parametre:

  • DateFrom = 2025-06-21
  • DateTo = 2025-07-21
  • Format = json
  • Page = 1
  • PageSize = 100

Anvender har allerede en tjenestebruger, som abonnementet er relateret til. Det er vigtigt at bemærke, at anvenderen kun kan modtage hændelser der er opstået efter tidspunktet hvor abonnementet blev oprettet – hændelser fra før dette tidspunkt er ikke tilgængelige. Anvender bruger sin tjenestebruger til at kalde REST-tjenesterne på URL'en:

  • https://services.datafordeler.dk/system/EventMessages/1.0.0/custom?datefrom=2025-06-21&dateto=2025-07-21&format=json&page=1&pagesize=100




Transition


  1. Anvender tilgår følgende tjeneste med sin API-nøgle key for at hente GraphQL-skemaet for BBR:
    1. https://graphql.datafordeler.dk/BBR/schema/v1?apiKey={noeglePlaceholder}xxxx
  2. Da anvender har dannet sig et overblik over GraphQL-skemaet og derfor ved hvilke queries der kan sendes for BBR, sender anvender nu query fra Figur 16 til URL'en nedenfor for at hente hændelser for BBR_Bygning med de ønskede oplysninger fra situationsbeskrivelsen:
    1. https://graphql.datafordeler.dk/BBR/v1?apiKey={noeglePlaceholder}xxxx




Code Block
query {
  BBR_Events(
    first: 100
    where: {
      and: [
        { entityname: { eq: "Bygning" } },
        { datafordelerOpdateringstid: { gte: "2025-06-21T00:00:00Z" } },
        { datafordelerOpdateringstid: { lte: "2025-07-21T23:59:59Z" } }
      ]
    }
  ) {
    pageInfo { hasNextPage endCursor }
    nodes {
      eventid entityname eventaction datafordelerRegisterImportSequenceNumber
      datafordelerOpdateringstid fromfailedimport object_id object_datafordelerRowId
      object_datafordelerRowVersion object_registreringfra object_registreringtil
      object_status object_virkningfra object_virkningtil
    }
  }
}




  1. Anvender får nu et respons tilbage fra Datafordeleren der indeholder hændelser indenfor de specificerede kriterier i JSON-format som vist i Figur 18 nedenfor (resultatet er kortet ned til kun at indeholde et eksempel på en hændelse).


Code Block
{
  "data": {
    "BBR_Events": {
      "pageInfo": {
        "hasNextPage": false,
        "endCursor": "TVE9PTs0L1lSQUFBQUFBQT0="
      },
      "nodes": [
        {
          "eventid": 1177315, "entityname": "Bygning", "eventaction": "i",
          "datafordelerRegisterImportSequenceNumber": 3453517,
          "datafordelerOpdateringstid": "2025-06-23T13:57:37.016852Z",
          "fromfailedimport": false,
          "object_id": "85209566-b4a4-4769-a016-13f4b7d4ce1d",
          "object_datafordelerRowId": "04816f75-71a4-4648-b978-5faf7fb0fb18",
          "object_datafordelerRowVersion": 1,
          "object_registreringfra": "2023-10-23T04:53:19.487369Z",
          "object_registreringtil": null,
          "object_status": "3",
          "object_virkningfra": "2023-02-28T07:54:30.700555Z",
          "object_virkningtil": "2023-10-23T04:53:19.487369Z"
        }
      ]
    }
  }
}







PUSH-hændelser


PUSH-hændelser kan ikke oversættes direkte til GraphQL, da de forudsætter al opsætningen til PULL-hændelser og endvidere konfiguration af et PUSH-endepunkt og en e-mail. Denne konfiguration skal foretages i Datafordeler administrationen, men eftersom PUSH hændelser udfases i takt med moderniserede hændelser gøres tilgængelig, findes den opsætning ikke længere.



Eftersom abonnering på moderniserede hændelser foregår via SSE, er dette unødvendigt, og derfor findes muligheden for at konfigurere et PUSH-endepunkt, som vist ovenfor, ikke i Datafordelerens nye brugerportal.

Der kan derfor tages udgangspunkt i querien fra afsnit 5.3.1 ({_}PULL-hændelser{_}), sammen med vejledningen fra afsnit 3.2 ({_}Abonnement på hændelser{_}). Dette vil resultere i nedenstående query, der kan bruges til at abonnere på hændelser via SSE.




Code Block
subscription {
  BBR_Events(
    where: {
      and: [
        { entityname: { eq: "Bygning" } }
      ]
    }
  ) {
    eventid entityname eventaction datafordelerRegisterImportSequenceNumber
    datafordelerOpdateringstid fromfailedimport object_id object_datafordelerRowId
    object_datafordelerRowVersion object_registreringfra object_registreringtil
    object_status object_virkningfra object_virkningtil
  }
}
Info

Bemærk

Filtreringen på datafordelerOpdateringstid er fjernet i dette eksempel, da det ikke vil give mening at filtrere på ved abonnering, eftersom hændelserne sendes til anvender løbende efter ny data er indlæst i Datafordeleren.