Dette dokument beskriver i detaljerer anvendelsen af HTTP-metoder og HTTP headere for REST webservices. Serviceanvendere og serviceudbydere i det fællesoffentlige it-landskab får på denne måde en grundmængde af ensartet syntaks og semantik ved anvendelsen og forståelsen af REST webservices.
Dokumentet er et bilag til de fællesoffentlige retningslinjer for webservices, beskrevet i ”Fælles retningslinjer for REST webservices” [WEBSER]. Læseren henvises til Retningslinjernes bilag 2 [WEBSER] for brug af HTTP-statuskoder i svar fra udstillede REST webservices.
Dokumentet er en konkretisering af følgende retningslinjer i [WEBSER]:
- R38 ”Anvend HTTP som fællesoffentlig REST kommunikationsprotokol”
- R39 ”Anvend HTTPs mekanismer til effektiv kommunikation”
For at sikre interoperabilitet mellem webservices er det en afgørende faktor, at kommunikationsprotokollen HTTP anvendes så ensartet som muligt på tværs af det fællesoffentlige it-landskab. HTTP er en standardiseret kommunikationsprotokol på applikationslaget i OSI modellen [OSIMODELLEN]. Protokollen fastlægger, hvordan en forespørgsel sendes fra en klient til en server, og et svar returneres. Mange udfaldsrum kan dog bestemmes af serviceudbyder, og derfor skal en række elementer af HTTP fastlægges for at sikre interoperabilitet.
Første afsnit indeholder indledning, præsenterer målgruppen og dennes behov, samt afgrænsninger i dokumentet.
Næste afsnit specificerer de konkrete elementer af http, der fastlægges.
Det afsluttende afsnit indeholder en liste over referencer.
Målgruppe
Dette dokuments målgruppe er personer hos serviceudbydere og serviceanvendere:
- Personer hos serviceudbydere er ansvarlige for at designe og realisere udstillede REST webservices. Dette kunne fx være it-udviklere eller it-arkitekter. Dokumentet skal bistå med hensigtsmæssigt design og realisering af REST webservices.
- Personer hos serviceanvendere skal udvikle integrationer til udstillede REST webservices. Dette kunne fx være it-udviklere eller it-arkitekter. Dokumentet kan imødekomme deres behov for at forstå, hvordan en REST webservice konkret skal anvendes.
Afgrænsning
Dokumentet afgrænser sig til at specificere, hvordan bestemte HTTP-metoder og HTTP headere anvendes.
Dele af HTTP, der ikke omtales i dette dokument, forholder dokumentet sig ikke til anvendelsen af.
Eksempelvis indeholder dette dokument ikke retningslinjer om caching. Det er serviceudbyderen, som er ansvarlig for at fastlægge og dokumentere anvendelsen. Serviceudbyderen kan eksempelvis vælge at følge HTTP-specifikationen for en REST webservice, hvor caching ønskes anvendt.
Brug af HTTP i REST webservices
HTTP er en ofte anvendt – grænsende til foretrukken – måde at udstille og anvende REST webservices på. Som en del af definitionen af REST [FIELDING], er der en række handlinger, som udføres på ressourcer. Når REST webservices udstilles via HTTP, skal serviceanvendere bruge HTTP-metoderne1 for at udføre ønskede handlinger på udstillede ressourcer. I tilgift hertil anvendes HTTP headere2. Alle HTTP-kald resulterer i et svar, hvor headere, der bl.a. indeholder HTTP-statuskoder3, bliver returneret.
Dette dokument fastlægger følgende:
- Betydningen af udvalgte HTTP-metoder (GET, PUT, osv.), så serviceanvendere forstår, hvilken operation på ressourcen de hver især svarer til.
- Betydningen af udvalgte HTTP headere (der sendes ved forespørgsel hhv. svar), så serviceanvendere forstår, hvordan HTTP headere anvendes.
Såfremt en REST webservice understøtter yderligere HTTP metoder og HTTP headere, er det serviceudstillerens ansvar at sikre dokumentation heraf.
Følgende afsnit beskriver fastlæggelsen af brugen af HTTP.
Brug af HTTP metoder ved udstilling af ressourcer
HTTP består jf. [HTTP] af en række metoder, der tilgår ressourcer udstillet via internettet. Dette afsnit fastlægger betydningen af udvalgte metoder, og serviceudbyder har ansvaret for at afgøre, om andre http metoder understøttes i en REST webservice, der tilgås via HTTP.
For at gøre det lettere for serviceanvendere skal HTTP-metoderne implementeres atomart4 hos serviceudbyderen, dvs. enten er handlingen svarende til metoden helt gennemført, eller også er den (slet) ikke gennemført. Et kald kan dog udføres asynkront, jf. Retningslinjernes bilag 2.
HTTP indeholder følgende metoder: GET, HEAD, POST, PUT, DELETE, PATCH, TRACE, CONNECT, og OPTIONS.
HTTP-metoderne PUT, GET, POST og DELETE svarer til ”CRUD” metoder til at oprette, læse, rette og slette objekter. HTTP-metoderne PATCH, HEAD og OPTIONS kan anvendes til yderligere funktionalitet i REST webservices.
HTTP-metoderne TRACE og CONNECT har begrænset anvendelse og er derfor ikke yderligere beskrevet i dette dokument.
PUT
HTTP-metoden PUT skal anvendes, når en ressource skal oprettes eller opdateres, og det er serviceanvenderen, der er ansvarlig for dette, inklusive at tildele ressourcen et unikt ID. HTTP-metoden PUT kan desuden oprette en hel kollektion af ressourcer ad gangen. HTTP-metoden PUT overskriver hele objektet eller hele kollektionen, hvis den findes i forvejen.
Eksempel:
En serviceanvender ønsker at oprette eller opdatere en sag med identifikator ”42” hos en Serviceudbyder. Serviceanvenderen angiver i sit kald HTTP-metoden PUT på følgende URI: ”…/api/sager/42” . Sammen med PUT-metoden medsender serviceanvenderen en header, og en body, som indeholder indhold for sagen med identifikator lig med 42.
Hvis en serviceanvender eksempelvis ønsker at oprette eller opdatere en kollektion af sager, angiver serviceanvenderen URI: ”/api/sager”. Sammen med HTTP-metoden PUT medsender serviceanvenderen en eller flere headere, og en body som indeholder indholdet for hele kollektionen.
PUT er idempotent, således at serviceanvenderen kan kalde PUT gentagne gange med samme resultat og konsekvenser, jf. [HTTP].
GET
HTTP-metoden GET skal anvendes til at tilgå eller fremsøge en ressource eller en kollektion af ressourcer, og serviceudbyder returnerer hele ressourcen eller hele kollektionen (eller den fremsøgte del). Der sker ingen opdatering ved at kalde GET én eller flere gange5.
Særligt bemærkes det, at HTTP-metoden POST kan anvendes i de tilfælde, hvor der skal medsendes parametre, som fx pga. forespørgslens størrelse eller kompleksitet ikke kan udtrykkes i en HTTP URL inklusive query string.
Eksempel:
En serviceanvender ønsker at hente en bestemt sag med identifikator ”1” hos en Serviceudbyder. Serviceanvenderen angiver HTTP-metoden GET på følgende URI: ”/api/sager/1”. ”. Sammen med HTTP-metoden GET medsender serviceanvenderen en eller flere headere. Servicen vil returnere et svar, som indeholder sagen med ident ”1”.
En serviceanvender, der ønsker at hente alle sager i kollektionen hos en Serviceudbyder, angiver denne URI: ”/api/sager/”.
Søgeparametre, der anvendes med HTTP-metoden GET, skal overholde R31. Hvis en serviceanvender således ønsker at fremsøge en eller flere sager i kollektionen af sager, hvor partsværdi er lig ”1234”, angiver serviceanvenderen HTTP-metoden GET med denne URI (bemærk brug af ”:” i søgetermen): ”/api/sager?q=part:1234”.
Serviceanvenderen skal kunne kalde GET gentagne gange med samme resultat og konsekvenser, idet GET er idempotent jf. [HTTP].
POST
HTTP-metoden POST skal anvendes, når en ressource skal oprettes, og det er serviceudbyderen, der er ansvarlig for forretningsobjektet inklusive at tildele det et unikt ID. HTTP-metoden POST overskriver hele ressourcen, hvis den findes i forvejen.
Eksempel:
En serviceanvender, der ønsker at oprette en sag, angiver serviceanvenderen HTTP-metoden POST på følgende URI: ”/api/sager”. Bemærk, at oprettelse sker ved at ”POSTe” til kollektionen ”sager”. Sammen med HTTP-metoden POST medsender serviceanvenderen en eller flere headere HTTP, og en body som indeholder indhold for sagen.
POST kan også anvendes til fremsøgning i de tilfælde, hvor GET ikke kan anvendes.
DELETE
HTTP-metoden DELETE skal anvendes, når en ressource skal slettes. HTTP-metoden DELETE kan kun slette individuelle ressourcer og anvendes ikke på kollektioner.
Eksempel:
En serviceanvender ønsker at slette en sag med ident ”42”, og angiver HTTP-metoden DELETE på følgende URI: ”/api/sager/42”. Sammen med HTTP-metoden DELETE medsender serviceanvenderen en eller flere HTTP headere.
Serviceanvenderen skal kunne kalde DELETE gentagne gange med samme resultat og konsekvenser, idet DELETE er idempotent jf. [HTTP].
HEAD
HTTP-metoden HEAD skal anvendes, når serviceanvender tilgår eller fremsøger en ressource eller en kollektion af ressourcer, men i modsætning til HTTP GET returneres kun metadata om ressourcen. Fx anvendes HEAD, hvis serviceanvender vil vide antallet af søgeresultater for en given forespørgsel.
Eksempel:
En serviceanvender ønsker at hente metadata om en bestemt sag med ident ”1”, og angiver HTTP-metoden HEAD på følgende URI: ”/api/sager/1”. Sammen med HTTP-metoden HEAD medsender serviceanvenderen en eller flere HTTP headere.
Serviceanvenderen skal kunne kalde HEAD gentagne gange med samme resultat og konsekvenser, idet HEAD er idempotent jf. [HTTP].
PATCH
Serviceanvendere kan bruge HTTP-metoden PATCH, når kun dele af en ressource skal opdateres (f.eks. bestemte attributter). De af ressourcens data, der ikke er angivet i forespørgslen, bevarer deres eksisterende værdier6 efter udførslen af HTTP-metoden PATCH.
OPTIONS
Serviceanvendere kan bruge HTTP-metoden OPTIONS til at opdage hvilke HTTP metoder, der kan anvendes på en udstillet ressource. Serviceudbyderen kan udstille HTTP-metoden OPTIONS som en del af REST webservicens dokumentation. Der henvises til Bilag 1 til [WEBSER].
Serviceanvenderen kan kalde OPTIONS gentagne gange med samme resultat og konsekvenser, idet OPTIONS er idempotent jf. [HTTP].
Anvendelse af HTTP headere ved forespørgsler
HTTP giver serviceanvendere mulighed for at medsende informationer i forbindelse med et kald [HTTP]. Disse yderligere data angives som en header i HTTP kaldet.
Serviceudstilleren skal understøtte, at følgende HTTP headere kan angives af serviceanvendere:
- Content-Type.
- Accept.
- Content-Encoding.
- Accept-Encoding.
- Accept-Language.
- OIOIDWS headere.
- Accept.
- X-HTTP-Method-Override.
- If-Match, jf. [WEBSER].
De følgende afsnit beskriver ovenstående headere, der skal anvendes ved forespørgsler til REST webservices, hvis den tilsvarende funktionalitet understøttes af serviceanvenderen.
Angivelse af datarepræsentation i forespørgsel
En serviceanvender skal anvende HTTP header til at indikere, hvilken datarepræsentation det medsendte body indeholder, f.eks. ved oprettelse eller opdatering af en ressource.
Hertil anvender serviceanvenderen HTTP headeren ”Content-Type”, som specificeret i [HTTP].
Serviceudbyderen skal følge indikationen, eller returnere en fejl, herunder hvis serviceanvenderen ikke har angivet datarepræsentationen, og dette er påkrævet.
Eksempel:
Hvis en serviceanvender eksempelvis sender et forretningsobjekt som ”JSON” (Javascript Object Notation) med UTF-8 tekst encoding via HTTP-metoden PUT, angiver serviceanvenderen denne header:
Content-Type: application/json;charset=UTF-8
Angivelse af datarepræsentation for svar
En serviceanvender bør anvende http-mekanismen ”content negotiation” til at indikere, hvilken datarepræsentation den ønskede REST ressource skal returneres i.
Hertil anvender serviceanvenderen HTTP headeren ”Accept”, som specificeret i [HTTP]. Angiver serviceanvenderen ikke et ønsket dataformat, skal serviceudbyderen selv vælge datarepræsentation.
Serviceudbyderen er forpligtet til at følge indikationen, eller returnere en fejl, hvis formatet ikke understøttes.
Eksempel:
Hvis en serviceanvender eksempelvis understøtter ”JSON” (Javascript Object Notation) eller XML som svar fra HTTP metoden GET, angiver serviceanvenderen denne header:
Accept: application/json, application/xml
Komprimering af forespørgsel
En serviceanvender skal anvende en HTTP header til at indikere, når serviceanvenderen har komprimeret data i et kald.
Hertil anvender serviceanvenderen HTTP headeren ”Content-Encoding” som specificeret i [HTTP].
Serviceudbyderen er forpligtet til at følge indikationen eller returnere en fejl.
Eksempel:
Hvis en serviceanvender eksempelvis har anvendt ”gzip” ved HTTP-metoden POST, angiver serviceanvenderen denne header:
Content-Encoding: gzip
Komprimering af svar
En serviceanvender bør anvende HTTP-mekanismen ”content negotiation” til at indikere, at serviceanvenderen ønsker svaret som komprimerede data (der fylder mindre).
Hertil skal serviceanvenderen anvende den eksisterende HTTP header ”Accept-Encoding”, som specificeret i [HTTP].
Serviceudbyderen er ikke forpligtet til at følge indikationen.
Eksempel:
Hvis en serviceanvender eksempelvis understøtter ”gzip” eller ”compress” som svar fra HTTP metoden GET, angiver serviceanvenderen denne header:
Accept-Encoding: gzip, compress
Sprog
En serviceanvender bør anvende HTTP-mekanismen ”content negotiation” til at indikere om serviceanvenderen kan behandle sprog.
Hertil skal serviceanvenderen anvende den eksisterende HTTP header ”Accept-Language”, som specificeret i [HTTP].
Serviceudbyderen skal følge indikationen. Hvis det angivne sprog ikke understøttes, eller hvis serviceanvenderen ikke har angivet et sprog, så bruges dansk. Hvis serviceanvender angiver flere sprog, så returneres det første understøttede sprog læst fra venstre mod højre.
Eksempel:
Hvis en serviceanvender eksempelvis understøtter ”da” og ”en” som svar fra HTTP-metoden GET, angiver serviceanvenderen denne header:
Accept-Language: da, en
Serviceudstiller vil returnere dansk som første prioritet, hvis det er muligt.
Sikkerhed
En REST webservice, der giver adgang til persondata eller anden fortrolig information, skal følge gældende krav til sikring af webservices, der er tilgængelige via internettet.
Sådanne REST webservices skal udstilles med brug af OIO IDWS REST profilen.
REST webservices som anvender sikkerhedsmodellen OIO IDWS REST kræver at serviceanvendere medsende headere som angivet i [OIOIDWS]. Dette vil sige headerne ”saml-token” (introduceret med OIO IDWS) og ”Authorization”.
Der henvises til [OIOIDWS] for eksempler.
Ønsket REST webservice version
En serviceanvender af en REST webservice, der tilgås via http, kan angive, at en bestemt version af REST webservicen ønskes kaldt.
Hertil skal serviceanvenderen anvende den eksisterende HTTP header ”Accept”, som specificeret i [HTTP], sammen med et ”version=” element.
Dette ”version” element skal i relation til REST webservices understøtte semantisk versionering, jf. retningslinje R17 i [WEBSER]. Versionselementet har tre komponenter: major, minor og micro, der angives adskilt af ’.’ (et punktum).
Serviceanvender kan via ”*” (en stjerne) angive, at micro, eller micro og minor kan have vilkårlige værdier. I så fald ønskes seneste (højeste) version af webservicen.
Serviceudbyderen er forpligtet til at følge indikationen eller returnere en fejl, hvis den angivne version ikke findes. Hvis intet er angivet, skal serviceudstiller anvende seneste (højeste) version.
Eksempler:
Hvis en serviceanvender eksempelvis ønsker version ”1.2.1”, angiver serviceanvenderen denne header:
Accept: version=1.2.1
Hvis en serviceanvender eksempelvis ønsker version ”1.2”, og ingen præferencer har for micro version, angiver serviceanvenderen denne header:
Accept: version=1.2.*
Hvis en serviceanvender eksempelvis ønsker version ”1”, og ingen præferencer har for minor og micro version, angiver serviceanvenderen denne header:
Accept: version=1.*
Ønsket HTTP-metode
Serviceanvenderen kan angive den ønskede HTTP-metode via en HTTP request header. Den bagvedliggende praksis herfor er, at nogle serviceanvendere er placerede bag netværksudstyr, der forhindrer visse HTTP-metoder.
Hertil anvender serviceanvenderen HTTP headeren ”X-HTTP-Method-Override”, og angiver ønsket HTTP metode (”POST”, ”GET”, ”PUT”, ”DELETE”, ”HEAD”, ”OPTIONS”, ”PATCH”) som værdi.
Serviceudbyderen er forpligtet til at følge indikationen eller returnere en fejl.
Eksempel:
Hvis serviceanvender eksempelvis ønsker at anvende HTTP-metoden ”PUT”, angiver serviceanvenderen denne header:
X-HTTP-Method-Override: PUT
Brug af HTTP headere i svar
HTTP giver jf. [HTTP] serviceudbydere mulighed for at medsende informationer i forbindelse med et svar (kaldt ”headere”).
Der er følgende headere:
- Content-Type.
- Content-Language.
- X-Total-Count.
- Link.
- Retry-After.
- Last-Modified.
- Statusline.
- X-Progress.
Følgende afsnit beskriver ovenstående headere, der kan anvendes i svar fra REST webservices.
Angivelse af datarepræsentation ved svar
Når en REST webservice returnerer ressourcer, skal den anvende HTTP-mekanismen ”content negotiation” til at indikere, hvilken datarepræsentation der anvendes.
Hertil anvender serviceudbyderen den eksisterende HTTP header ”Content-Type”, som specificeret i [HTTP].
Eksempel:
Hvis en REST webservice eksempelvis sender et forretningsobjekt som ”JSON” (Javascript Object Notation) med UTF-8 tekst encoding ved svar, returnerer webservicen denne header:
Content-Type: application/json;charset=UTF-8
Sprog
Når en REST webservice returnerer meddelelser (f.eks. fejlmeddelelser jf. Bilag 2 til [WEBSER]), skal sproget for fejlmeddelelsen angives.
Hertil anvender serviceudbyderen den eksisterende HTTP header ”Content-Language”, som specificeret i [HTTP].
Eksempel:
Hvis eksempelvis fejlmeddelelser returneres på dansk, returnerer REST webservicen denne header:
Content-Language: da
Antal fundne ressourcer ved søgninger
En REST webservice, der returnerer et antal ressourcer, der er fremfundet ved søgning (se f.eks. retningslinje R31 i [WEBSER]), kan returnere det samlede antal ressourcer, søgningen kunne returnere som en særlig HTTP header i svaret.
Hertil anvendes HTTP headeren ”X-Total-Count”. Hvis headeren er til stede i et svar, skal værdien være et helt tal, større end eller lig 0. En indikation af 0 skal betyde, at der ingen ressourcer var. Hvis serviceudbyderen ikke kan angive antallet af ressourcer, må headeren ikke være angivet i svaret, eller også skal værdien være tom.
Eksempel:
Hvis der eksempelvis var i alt 42 ressourcer i en søgning, returnerer REST webservicen denne header:
X-Total-Count: 42
Link header
En REST webservice kan anvende ”Link”, defineret i RFC 8288, som dokumentation af den udstillede ressource. Der henvises til Bilag 1 til [WEBSER] for dokumentation.
En REST webservice kan yderligere angive, at en fremsøgt ressource er en del af en kollektion ved at anvende ”next”, ”previous”, ”first” og ”last”, via en HTTP header ”Link” defineret i RFC 8288.
Eksempel:
Hvis eksempelvis ressourcen er det andet element i en kollektion bestående af tre elementer, kan REST webservicen returnere denne header (i én lang linje):
Link: <http://server.dk/api/sager/3>;rel=”next”; <http://server.dk/api/sager/1>;rel=”previous”; <http://server.dk/api/sager/1>;rel=”first”; <http://server.dk/api/sager/3>;rel=”last”
Asynkrone kald
En serviceudstiller kan indikere, at svar på en forespørgsel ikke er til stede nu, men på et senere tidspunkt.
Hertil anvender serviceanvenderen HTTP headeren ”Retry-After”, som specificeret i [HTTP]. Angivelsen kan være et heltal, der betyder det samme antal sekunder, men også et tidspunkt der er et UTC datoformat, fx ”1999-12-31T23:59:59Z”
For asynkrone svar på forespørgsler henvises til Retningslinjernes bilag 2, under punkt 2.1.
Eksempel:
En serviceanvender kan forespørge på et givet svar, men kan få en meddelelse om at vente 5 minutter, returnerer REST webservicen denne header, hvor data angives i sekunder:
Retry-After: 300
Modifikationstidspunkt
En serviceudbyder kan indikere, hvornår en ressource senest er modificeret. Datoer skal altid returneres i UTC format.
Hertil anvender serviceudbyderen den eksisterende HTTP header ”Last-Modified”, som specificeret i [HTTP]. Der henvises til Retningslinjernes bilag 2.
[WEBSER] Eksempel:
En ressource er sidst modificeret sekundet før nytår 2000 i henhold til CET. Her returnerer REST webservicen denne header:
Last-Modified: 1999-12-31T23:59:59+01:00
Fejlinformationer
En serviceudbyder kan indikere angive informationer om opståede fejl.
Hertil anvender serviceudbyderen den eksisterende HTTP header ”Statusline”, som specificeret i [HTTP]. [WEBSER] Der henvises til Retningslinjernes bilag 2 for detaljer om headerens indhold.
Kilder
ID |
Kilde |
---|---|
[WEBSER] |
Digitaliseringsstyrelsen (2017) Fælles retningslinjer for REST webservices”. Tilgængelig på: https://arkitektur.digst.dk/metoder/retningslinjer-webservices |
[HTTP] |
“Hypertext Transfer Protocol (HTTP/1.1)”, RFC 7230, 7231, 7232, 7233, 7234, 7235. |
[FIELDING] |
Roy Fielding (2000) Architectural Styles and the Design of Network-based Software Architectures. Tilgængelig på: https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm |
[OIOIDWS] |
Digitaliseringsstyrelsen (2016) OIO IDWS REST profile”. Tilgængelig på: https://github.com/digst/OIOIDWS.Net |
[OSIMODELLEN] |
ISO/IEC 7498-1. Tilgængelig på: https://www.iso.org/standard/20269.html |
Fodnoter
1 F.eks. PUT (lagrer) og GET (henter).
2 F.eks. ”Accept”. HTTP headere kan forekomme i både forespørgsel og svar.
3 Anvendelsen af HTTP-statuskoder er beskrevet i bilag 2 til [WEBSER].
4 Atomar skal her forstås i transaktionel sammenhæng, svarende til ”atomic” egenskaben i transaktionssystemer, der overholder ACID.
5 I denne forbindelse anses logning ikke for en opdatering.
6 Tidligere skal i denne sammenhæng forstås som ”lige før operationen påbegyndes”.