Den gode webservice

Den gode webservice

1. Formål og anvendelsesområde

Denne side fastlægger obligatoriske principper for udvikling af REST-services i DFDG.

Retningslinjerne gælder for:

  • Alle services udstillet af DFDG

  • Alle forretningsdomæner

  • Alle integrationer mod eksterne aftagere

REST er den eneste gældende integrationsform for synkrone services i DFDG.


2. Grundprincipper

En DFDG-service:

  • skal understøtte et klart afgrænset forretningsdomæne

  • må ikke udvikles specifikt til én aftager

  • skal kunne understøtte flere aftageres behov

  • skal være stabil og forudsigelig over tid

  • skal designes ud fra forretningskontekst – ikke teknisk convenience

Ét forretningsansvar pr. service.

En service kan være StatusService, Domæneservice eller RuleService jf. https://starwiki.atlassian.net/wiki/spaces/FYS/pages/1433370736.

  • StatusService udstiller aktuel status og overblik (ingen historik).

  • Domæneservice udstiller forretningsmæssige entiteter, CRUD og eventuel historik.

  • RuleService udstiller gældende forretningsregler og er ikke person- eller virksomhedsspecifik.

Valg af servicetype skal være eksplicit og begrundet i forretningsbehov.


3. REST-arkitektur

DFDG følger REST-principperne beskrevet i: https://starwiki.atlassian.net/wiki/spaces/CITY/pages/1406926851/Star.Foundation+-+Teknisk+dokumentation#REST-principper
Følgende er obligatorisk:

  • Ressourcer navngives som substantiver

  • HTTP-verber anvendes korrekt (GET, POST, PUT, DELETE)

  • PATCH understøttes ikke

  • JSON anvendes som dataformat

  • Routes versioneres via URL (v1, v2, …)

  • CRUD er udgangspunktet

Handlinger (actions)

Handlinger (/action/...) må kun anvendes når:

  • forretningslogik påvirker flere ressourcer samtidig

  • der udføres en samlet forretningsproces, som ikke kan udtrykkes som klassisk CRUD

  • der foretages søgninger, hvor søgeparametre er så mange eller så komplekse, at de ikke hensigtsmæssigt kan angives som query-parametre i et GET-kald

Actions må ikke anvendes som generel erstatning for CRUD.


4. Kontraktdesign og DTO-principper

4.1 Isolation af kontrakter

DTO’er:

  • må ikke genbruges mellem services

  • må ikke genbruges mellem versioner af samme service

  • må ikke deles på tværs af forretningsdomæner

Dette for at undgå:

  • utilsigtede breaking changes

  • kobling mellem services

  • påvirkning af eksterne aftagere

Kontrakten isoleres – ikke domænelogikken.


4.2 OIO-typer og valideringsattributter

For OIO-typer såsom CPR-nummer er der etableret dedikerede valideringsattributter, som kan anvendes til dekorering af properties i DTO’er.

Disse attributter sikrer ensartet syntaksvalidering på tværs af services og skal anvendes, hvor det er relevant.

Der må ikke etableres egne parallelle valideringsmekanismer for disse typer.


4.3 Forretningsmodel og logik

Den interne forretningsmodel og forretningslogik SKAL som udgangspunkt genbruges mellem versioner af samme service.

Det er udelukkende kontrakten (DTO’er og API-snitflade), der isoleres mellem versioner.

Versionering må ikke føre til:

  • duplikeret forretningslogik

  • parallelle domænemodeller

  • divergerende forretningsregler mellem versioner uden saglig begrundelse (lovændringer)

Lovændringer

Hvis ændret lovgivning medfører ændrede forretningsregler:

  • skal der etableres en ny serviceversion

  • den nye version må implementere de ændrede forretningsregler

  • tidligere versioner bevarer de forretningsregler, der var gældende ved versionens etablering

Der må ikke introduceres versionsafhængig forretningslogik inden for samme serviceversion.

Forretningsregler skal være konsistente og deterministiske inden for den enkelte version.


4.4 Borgerrelateret oprettelse og opdatering

Ved oprettelse eller opdatering af data, der direkte relaterer sig til en borger, skal personnummer indgå som en del af input.

Dette gælder uanset om:

  • der arbejdes på en entitet identificeret via GUID

  • entiteten allerede eksisterer

Personnummer skal indgå af hensyn til:

  • sikkerhed

  • sporbarhed

  • korrekt kontekstafgrænsning

RuleServices er undtaget, da de ikke er person- eller virksomhedsspecifikke.


5. Versionering

Versionering sker udelukkende via URL:

/v1/ressource /v2/ressource

Principper:

  • Breaking changes kræver ny version

  • Non-breaking changes kan foretages uden versionsskift

  • Nuværende og forrige version skal kunne sameksistere

  • Udfasning varsles og aftales med aftagere

  • Kodelisteændringer kræver ikke versionsskift


5.1 Historik og GetHistory-principper

Historik udstilles kun, hvor der er et forretningsmæssigt behov.

En Domæneservice:

  • kan indeholde en særskilt GetHistory-metode

  • må ikke blande aktuel status og historik i samme respons

  • skal tydeligt adskille revisionshistorik fra liste-services

Der skal skelnes mellem:

  • Revisionshistorik (ændringer på samme entitet over tid)

  • Liste-services (kollektion af entiteter, hvor hvert element fremstår i seneste revision)


5.2 StatusService og historik

En StatusService må kun udstille aktuel status (og evt. planlagt/fremtidig status, hvis dette er relevant for forretningsmæssigt overblik).

En StatusService må ikke udstille:

  • afsluttede eller forhenværende forhold (historiske data)

  • revisionshistorik (ændringer over tid)

For tidsafgrænsede forhold gælder:

  • Aktuel status = forhold der pågår nu eller træder i kraft fremadrettet

  • Historik = forhold der er afsluttet og alene er relevante som tilbageblik

Hvis der er behov for afsluttede forhold eller revisionshistorik, skal dette udstilles via Domæneservice (Get/GetHistory) eller via en dedikeret liste-service


5.3 Konsistens og uforanderlighed over tid

Historik skal være konsistent med versioneringsprincipperne og må ikke ændre tidligere registrerede forretningsdata.


6. Dokumenthåndtering, herunder store dokumenter

6.1 Arkitekturprincip

DFDG har ét fælles dokumentarkiv i forretningsdomænet Dokumentarkiv.

Dokumentarkivet er eneste autoritative lagringssted gældende for dokumenter.

Andre forretningsdomæner må ikke etablere egne dokumentlagre.


6.2 Ansvarsfordeling

Forretningsdomæner med dokumentbehov:

  • skal selv udstille upload- og hent-services

  • må ikke eksponere Dokumentarkivets interne model

  • skal referere dokumenter via DocumentIdentifier (GUID)

Forretningsdomænet ejer forretningskonteksten.
Dokumentarkivet ejer dokumentet.


6.3 Kontraktprincipper

Dokumenter:

  • identificeres entydigt via GUID

  • må ikke oprettes med ugyldigt identifier

  • må ikke indlejres i generelle forretnings-DTO’er

  • skal hentes via dedikeret GET-endpoint

Dokumentindhold (fx binært indhold eller base64) må ikke returneres som en del af samlede forretningsobjekter eller større datasæt.

Det betyder, at dokumentindhold ikke må indgå i:

  • StatusServices

  • liste-services

  • søgeresultater

  • eller andre responser, der returnerer flere forretningsobjekter samlet

Dokumentindhold skal altid hentes via et særskilt, dedikeret endpoint.


6.4 Størrelse og type

Forretningsdomænet skal:

  • fastlægge maksimal dokumentstørrelse

  • validere dokumenttype

  • dokumentere begrænsninger i kontrakten


6.5 Adgang og events

Adgang følger det tilknyttede forretningsobjekt.

  • Dokumentindhold må ikke indgå i WSB’er

  • Events må kun indeholde reference (DocumentIdentifier)

Dokumentudlevering skal ske via autoriseret GET.


7. Validering og sanitering

7.1 Inputvalidering

Input skal valideres når:

  • datakvalitet påvirker borgerens rettigheder

  • sammenhænge i data er kritiske

  • data indgår i tilsyn eller målepunkter


7.2 HTML-sanitering (obligatorisk)

Alle tekstfelter:

  • saniteres for HTML og skadelige HTML tags

  • beskyttes mod XSS

Sanitering er en del af sikkerhedsmodellen – ikke kun datavalidering.


8. Sikkerhed og identifikation

Alle services:

  • skal følge DFDG’s gældende sikkerhedsmodel

  • skal identificere hvem der foretager kaldet

  • skal logge kald med korrelations-ID

Logning foretages via Star.Foundation, hvilket sikrer:

  • ensartet struktur

  • fælles korrelations-ID

  • ensartet metadata

  • centraliseret håndtering af logniveauer

Teams må ikke implementere egen alternativ logningsmekanisme for services.

Services må ikke udstilles uden adgangskontrol, medmindre de eksplicit er offentlige.


9. Webservicebeskeder (WSB)

DFDG anvender Webservicebeskeder (WSB) til asynkron kommunikation.

WSB’er:

  • pushes til aftagere

  • publiceres ved oprettelse, ændring eller sletning af relevante data

  • skal være konsistente med den synkrone REST-kontrakt

  • skal som hovedregel være uden body (ekstern data indhold)

  • må ikke indeholde fritekstfelter i bodý, når en sådan undtagelsesvist tillades

Synkron REST og asynkron WSB skal designes samlet, så:

  • hændelser afspejler faktiske forretningsændringer

  • aftagere kan reagere deterministisk

  • integrationer ikke kræver polling


10. Ændringer og varsling

Ved ændringer i servicesnitflader:

  • Breaking changes kræver ny version

  • Eksterne aftagere skal varsles

  • Ændringer skal accepteres før idriftsættelse

  • Samtidige ændringer hos alle aftagere skal undgås

Lovgivning kan undtagelsesvist kræve simultan ændring.


11. Anti-patterns (må ikke forekomme)

  • Service udviklet kun til én aftager

  • Genbrug af DTO mellem versioner

  • Breaking change uden ny version

  • Manglende sanitering af HTML

  • Overbelastede generiske services

  • SOAP-terminologi eller WSDL-tænkning