Are HTTP methods idempotent?

Idempotens: Hvad er det og hvorfor er det vigtigt?

04/07/2004

Rating: 4.14 (1851 votes)

Har du nogensinde oplevet at trykke på en "køb"-knap på en webshop, hvorefter internetforbindelsen blev langsom eller hakkede? Usikkerheden melder sig: Gik betalingen igennem? Skal jeg trykke igen? Frygten for at blive trukket dobbelt for den samme vare er reel. Dette scenarie illustrerer perfekt, hvorfor et koncept kaldet idempotens er afgørende i den digitale verden. Det er et fundamentalt princip for at bygge pålidelige og forudsigelige systemer, især når det kommer til webapplikationer og API'er. Uden idempotens ville internettet være et langt mere kaotisk sted, fyldt med utilsigtede duplikeringer af handlinger.

What are idempotent operations?
GET, HEAD, and OPTION are clearly idempotent as they only read data, but don’t create, update or delete any resources. PUT is idempotent as it updates a resource or creates a new one if it doesn’t exist. If we sent the same update multiple times, the resource shouldn’t change. 4.3. Non-Idempotent Operations
Indholdsfortegnelse

Hvad Betyder Idempotens Helt Præcist?

Kort sagt er en operation idempotent, hvis resultatet af at udføre den én gang er præcis det samme som at udføre den flere gange. Efter den første succesfulde udførelse vil yderligere identiske forsøg ikke ændre systemets tilstand. Ordet stammer fra de latinske ord "idem" (samme) og "potens" (kraft), hvilket bogstaveligt talt betyder "samme kraft" eller "samme effekt".

For at gøre det mere konkret, lad os se på et par simple eksempler:

  • Et idempotent eksempel (matematik): Funktionen, der finder den absolutte værdi af et tal. Hvis du tager den absolutte værdi af -5, får du 5. Hvis du tager den absolutte værdi af resultatet (5) igen, får du stadig 5. Uanset hvor mange gange du anvender funktionen, forbliver resultatet 5.
  • Et ikke-idempotent eksempel (matematik): En funktion, der vender fortegnet på et tal. Hvis du starter med 5 og vender fortegnet, får du -5. Hvis du gør det igen, får du 5. Hver operation ændrer resultatet.
  • Et idempotent eksempel (hverdagsliv): At kalde på en elevator. Du trykker på knappen for at kalde elevatoren til din etage. Elevatoren registreres som kaldt. Hvis du utålmodigt trykker på knappen ti gange mere, ændrer det ikke noget. Elevatoren er allerede på vej; din handling har ingen yderligere effekt på systemets tilstand.
  • Et ikke-idempotent eksempel (hverdagsliv): At tænde og slukke for en lyskontakt. Hver gang du trykker på kontakten, ændres lysets tilstand fra tændt til slukket eller omvendt. Handlingen er ikke idempotent.

I softwareudvikling er dette koncept kritisk. Når en klient (f.eks. en webbrowser eller en mobilapp) sender en anmodning til en server, kan ting gå galt. Netværksfejl kan betyde, at klienten aldrig modtager en bekræftelse, selvom serveren har udført handlingen. Uden idempotens ville klientens eneste sikre mulighed være at spørge brugeren, hvilket er upraktisk. Med idempotens kan klienten blot sende den samme anmodning igen, velvidende at det ikke vil forårsage utilsigtede bivirkninger.

Hvorfor er Idempotens Vigtigt? Et Eksempel fra den Virkelige Verden

Den bedste måde at forstå værdien af idempotens på er gennem et praktisk eksempel, som mange af os kan relatere til: online betalinger.

What is an idempotent API?
In the realm of RESTful web services, idempotency relates to the concept that making the same API request multiple times should yield the same result as making it just once. This means that regardless of how many times you repeat an idempotent request, the outcome remains consistent. 1.

Scenarie uden Idempotens

Forestil dig, at du overfører 100 kr. til en ven via en betalingsapp. Din app sender en anmodning til betalingstjenestens server.

  1. Du sender anmodningen: "Overfør 100 kr. til Ven A".
  2. Serveren modtager anmodningen, trækker 100 kr. fra din konto og overfører dem til Ven A.
  3. Lige da serveren skal sende en bekræftelse tilbage til din app, opstår der en netværksfejl. Du modtager aldrig bekræftelsen.
  4. Din app viser en fejlmeddelelse: "Overførsel mislykkedes. Prøv igen."
  5. Du, som en forsigtig bruger, prøver igen. Du sender den præcis samme anmodning.
  6. Serveren, som ikke har nogen anelse om, at dette er et genforsøg, behandler det som en helt ny anmodning. Den trækker yderligere 100 kr. fra din konto og overfører dem til Ven A.

Resultatet? Du har utilsigtet overført 200 kr. i stedet for 100 kr. Dette er en katastrofal fejl, som skyldes, at overførselsoperationen ikke var idempotent.

Løsningen: Idempotensnøglen

For at løse dette problem introducerer man en idempotensnøgle. Dette er en unik identifikator (ofte en lang, tilfældig streng som en UUID), som klienten genererer for hver unik operation.

Lad os se på det samme scenarie, men denne gang med en idempotent implementering:

  1. Din app genererer en unik nøgle for denne specifikke transaktion, f.eks. "xyz-123-abc".
  2. Du sender anmodningen: "Overfør 100 kr. til Ven A med idempotensnøgle 'xyz-123-abc'".
  3. Serveren modtager anmodningen. Den tjekker først sin database for at se, om den nogensinde har behandlet en anmodning med nøglen 'xyz-123-abc'.
  4. Da nøglen er ny, udfører serveren overførslen og gemmer resultatet sammen med nøglen 'xyz-123-abc'.
  5. Netværksfejlen opstår igen, og du modtager ikke bekræftelsen.
  6. Du prøver igen og sender den præcis samme anmodning, inklusiv den samme idempotensnøgle 'xyz-123-abc'.
  7. Serveren modtager anmodningen og tjekker sin database. Denne gang finder den nøglen 'xyz-123-abc'. Den ved nu, at denne operation allerede er blevet succesfuldt udført.
  8. I stedet for at udføre overførslen igen, slår serveren det gemte resultat op og sender den oprindelige bekræftelse tilbage til din app.

Resultatet er, at pengene kun bliver overført én gang. Du kan trygt prøve igen så mange gange, du vil, uden frygt for dobbeltbetalinger. Ulempen er, at serveren skal gemme disse nøgler i en periode, men det er en lille pris at betale for et robust system.

What are idempotent operations?
GET, HEAD, and OPTION are clearly idempotent as they only read data, but don’t create, update or delete any resources. PUT is idempotent as it updates a resource or creates a new one if it doesn’t exist. If we sent the same update multiple times, the resource shouldn’t change. 4.3. Non-Idempotent Operations

Idempotens i REST API'er og HTTP-Metoder

Konceptet om idempotens er dybt integreret i designet af internettets protokoller, især HTTP, som er grundlaget for REST API'er. Når udviklere bygger API'er, er det afgørende at respektere de idempotente egenskaber ved de forskellige HTTP-metoder for at sikre forudsigelig adfærd.

Her er en oversigt over de mest almindelige HTTP-metoder og deres idempotente status:

HTTP-MetodeEr Idempotent?Er Sikker?Beskrivelse
GETJaJaBruges til at hente data. Ændrer ikke serverens tilstand.
HEADJaJaHenter kun metadata (headers), ikke selve dataene. Ændrer ikke tilstand.
OPTIONSJaJaBeskriver kommunikationsmulighederne for en ressource.
PUTJaNejBruges til at oprette eller fuldstændigt erstatte en ressource.
DELETEJaNejBruges til at slette en ressource.
POSTNejNejBruges typisk til at oprette en ny underordnet ressource.
PATCHNejNejBruges til at lave en delvis opdatering af en ressource.

De Idempotente Metoder

GET, HEAD, OPTIONS: Disse metoder er defineret som "sikre", hvilket betyder, at de kun er til for at læse data og ikke må ændre serverens tilstand. Fordi de ikke ændrer noget, er de per definition også idempotente. At bede om de samme oplysninger flere gange ændrer ikke på oplysningerne selv.

PUT: Denne metode bruges til at erstatte en ressource fuldstændigt på en given URL. Hvis du sender en PUT-anmodning for at opdatere en brugers profil med de samme oplysninger flere gange, er resultatet det samme: brugerens profil indeholder præcis de data, du sendte. Den første anmodning udfører opdateringen, og de efterfølgende anmodninger overskriver blot med de samme data, så tilstanden forbliver uændret.

Are methods idempotent?
"Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE should not have side effects, and so are inherently idempotent."

DELETE: Dette kan virke kontraintuitivt, men DELETE er idempotent. Den første anmodning om at slette en ressource vil slette den. Serveren svarer typisk med en succes-kode (f.eks. 204 No Content). Hvis du sender den samme DELETE-anmodning igen, er ressourcen allerede væk. Serveren vil nu sandsynligvis svare med en 404 Not Found-fejl. Selvom svaret er forskelligt, er serverens tilstand uændret efter den første anmodning. Ressourcens tilstand er "slettet", og den forbliver "slettet". Dette er kernen i idempotens: det handler om serverens tilstand, ikke serverens svar.

De Ikke-Idempotente Metoder

POST: Dette er den klassiske metode til at oprette en ny ressource. Hvis du sender en POST-anmodning til `/articles` for at oprette en ny artikel, vil hver succesfuld anmodning oprette en ny, unik artikel i databasen. At sende den samme anmodning fem gange vil resultere i fem identiske artikler, hver med sit eget unikke ID. Derfor er POST ikke idempotent.

PATCH: Denne metode bruges til delvise opdateringer. Dens idempotens afhænger af selve operationen. En PATCH-anmodning, der siger "sæt brugerens alder til 30", er idempotent. Men en anmodning, der siger "forøg brugerens alder med 1", er ikke. Hvis du sender sidstnævnte anmodning to gange, vil alderen stige med to. Da HTTP-specifikationen ikke kan garantere, hvordan PATCH vil blive brugt, klassificeres den som ikke-idempotent.

Ofte Stillede Spørgsmål (FAQ)

Er "idempotent" det samme som "sikker" (safe)?

Nej, det er to forskellige, men relaterede, koncepter. En sikker metode er en, der ikke ændrer serverens tilstand (f.eks. GET). En idempotent metode er en, hvor gentagne anmodninger ikke ændrer tilstanden ud over den første anmodning (f.eks. PUT, DELETE). Alle sikre metoder er pr. definition idempotente, men ikke alle idempotente metoder er sikre. PUT og DELETE ændrer serverens tilstand, så de er ikke sikre, men de er idempotente.

What is idempotent in http?
Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request. [...] Summarizing, the HTTP methods are classified as following:

Hvad sker der præcist, når jeg kalder en DELETE-anmodning to gange?

Den første anmodning finder ressourcen, sletter den og returnerer en succes-statuskode, typisk `200 OK` eller `204 No Content`. Serverens tilstand er nu ændret: ressourcen eksisterer ikke længere. Den anden anmodning (og alle efterfølgende) vil forsøge at slette den samme ressource, men den findes ikke. Derfor vil serveren returnere en fejl-statuskode, typisk `404 Not Found`. Selvom du modtager forskellige svar, er serverens endelige tilstand (at ressourcen er slettet) den samme efter den første anmodning som efter den tiende. Det er dette, der gør DELETE idempotent.

Kan en POST-anmodning gøres idempotent?

Ja, det kan den, og det er en meget almindelig praksis for kritiske systemer som betalingsgateways. Selvom POST-metoden ifølge HTTP-standarden ikke er idempotent, kan udviklere implementere idempotens ved hjælp af en idempotensnøgle, som beskrevet i betalingseksemplet tidligere. Klienten sender en unik nøgle i anmodningens header eller body, og serveren bygger logik til at sikre, at handlingen kun udføres én gang pr. unik nøgle. Dette giver robustheden fra idempotens til operationer, der semantisk passer bedst til POST-metoden.

Konklusion

Idempotens er mere end bare et teknisk begreb; det er en fundamental byggesten for at skabe pålidelige, forudsigelige og fejltolerante systemer på internettet. Ved at forstå, hvordan forskellige HTTP-metoder opfører sig, og ved at anvende strategier som idempotensnøgler, kan udviklere designe API'er, der håndterer uundgåelige netværksfejl og genforsøg elegant. Næste gang din app hænger, mens du foretager en betaling, kan du have lidt mere ro i sindet, velvidende at kloge udviklere sandsynligvis har brugt princippet om idempotens til at sikre, at du ikke ender med at betale dobbelt.

Hvis du vil læse andre artikler, der ligner Idempotens: Hvad er det og hvorfor er det vigtigt?, kan du besøge kategorien Teknologi.

Go up