Bedste fremgangsmåder til REST API-fejlhåndtering

1. Introduktion

REST er en statsløs arkitektur, hvor klienter kan få adgang til og manipulere ressourcer på en server. Generelt bruger REST-tjenester HTTP til at reklamere for et sæt ressourcer, som de administrerer, og leverer en API, der giver klienter mulighed for at få eller ændre tilstanden for disse ressourcer.

I denne vejledning lærer vi om nogle af de bedste fremgangsmåder til håndtering af REST API-fejl, herunder nyttige tilgange til at give brugerne relevant information, eksempler fra store websteder og en konkret implementering ved hjælp af et eksempel på Spring REST-applikation.

2. HTTP-statuskoder

Når en klient fremsætter en anmodning til en HTTP-server - og serveren modtager anmodningen med succes - serveren skal underrette klienten, hvis anmodningen blev håndteret med succes eller ej. HTTP opnår dette med fem kategorier af statuskoder:

  • 100-niveau (informativ) - Server anerkender en anmodning
  • 200-niveau (succes) - Server afsluttede anmodningen som forventet
  • 300-niveau (omdirigering) - Kunden skal udføre yderligere handlinger for at fuldføre anmodningen
  • 400-niveau (klientfejl) - klienten sendte en ugyldig anmodning
  • 500-niveau (serverfejl) - Serveren opfyldte ikke en gyldig anmodning på grund af en fejl med serveren

Baseret på svarkoden kan en klient overbevise resultatet af en bestemt anmodning.

3. Håndtering af fejl

Det første trin i håndtering af fejl er at give en klient en korrekt statuskode. Derudover kan det være nødvendigt at vi giver mere information i reaktionsorganet.

3.1. Grundlæggende svar

Den enkleste måde, vi håndterer fejl på, er at svare med en passende statuskode.

Nogle almindelige svarkoder inkluderer:

  • 400 Dårlig anmodning - Kunden sendte en ugyldig anmodning - som f.eks. Mangler den krævede anmodningsinstans eller parameter
  • 401 Uautoriseret - Klienten kunne ikke godkendes med serveren
  • 403 Forbidden - Klient godkendt, men har ikke tilladelse til at få adgang til den ønskede ressource
  • 404 Ikke fundet - Den ønskede ressource findes ikke
  • 412 Forudsætning mislykkedes - En eller flere betingelser i felterne i anmodningsoverskriften vurderet til falsk
  • 500 intern serverfejl - Der opstod en generisk fejl på serveren
  • 503 Service utilgængelig - Den ønskede service er ikke tilgængelig

Mens de er grundlæggende, tillader disse koder en klient at forstå den brede karakter af den fejl, der opstod. For eksempel ved vi, hvis vi modtager en 403-fejl, at vi mangler tilladelser til at få adgang til den ressource, vi anmodede om.

I mange tilfælde er vi dog nødt til at give supplerende detaljer i vores svar.

500 fejl signalerer, at der opstod nogle problemer eller undtagelser på serveren under håndtering af en anmodning. Generelt er denne interne fejl ikke vores kundes forretning.

Derfor for at minimere en sådan type svar til klienten, vi skal flittigt forsøge at håndtere eller fange interne fejl og svare med andre passende statuskoder, hvor det er muligt. For eksempel, hvis en undtagelse opstår, fordi en anmodet ressource ikke findes, skal vi udsætte dette for en 404-snarere end en 500-fejl.

Dette betyder ikke, at 500 aldrig skal returneres, kun at det skal bruges til uventede forhold - såsom et serviceafbrydelse - der forhindrer serveren i at udføre anmodningen.

3.2. Standard forårssvar

Disse principper er så allestedsnærværende, at Spring har kodificeret dem i sin standardfejlhåndteringsmekanisme.

For at demonstrere antager vi, at vi har en simpel Spring REST-applikation, der administrerer bøger med et slutpunkt til at hente en bog efter dens ID:

krølle -X GET -H "Accepter: applikation / json" // localhost: 8082 / spring-rest / api / book / 1

Hvis der ikke er nogen bog med ID 1, forventer vi, at vores controller kaster en BookNotFoundException. Når vi udfører en GET på dette slutpunkt, ser vi, at denne undtagelse blev kastet, og responsorganet er:

{"tidsstempel": "2019-09-16T22: 14: 45.624 + 0000", "status": 500, "error": "Intern serverfejl", "message": "Ingen meddelelse tilgængelig", "path": " / api / book / 1 "}

Bemærk, at denne standardfejlbehandler inkluderer en tidsstempel for, hvornår fejlen opstod, HTTP-statuskoden, en titel (den fejl felt), en meddelelse (som standard er tom) og URL-stien, hvor fejlen opstod.

Disse felter giver en klient eller udvikler information til at hjælpe med at foretage fejlfinding af problemet og udgør også et par af de felter, der udgør standardfejlhåndteringsmekanismer.

Derudover skal du bemærke, at Spring automatisk returnerer en HTTP-statuskode på 500, når vores BookNotFoundException kastes. Selvom nogle API'er returnerer en 500-statuskode eller andre generiske, som vi vil se med Facebook- og Twitter-API'erne - for alle fejl for enkelheds skyld det er bedst at bruge den mest specifikke fejlkode, når det er muligt.

I vores eksempel kan vi tilføje en @ControllerAdvice således at når en BookNotFoundException kastes, giver vores API en status på 404, der skal betegnes Ikke fundet i stedet for 500 Intern serverfejl.

3.3. Flere detaljerede svar

Som det ses i ovenstående Spring-eksempel, er nogle gange en statuskode ikke nok til at vise specifikationerne for fejlen. Når det er nødvendigt, kan vi bruge svaret til at give klienten yderligere oplysninger. Når vi leverer detaljerede svar, skal vi inkludere:

  • Fejl - En unik identifikator for fejlen
  • Besked - En kort menneskelig læsbar besked
  • Detalje - En længere forklaring på fejlen

For eksempel, hvis en klient sender en anmodning med forkerte legitimationsoplysninger, kan vi sende et 401-svar med et organ på:

{"error": "auth-0001", "message": "Forkert brugernavn og adgangskode", "detail": "Sørg for, at det brugernavn og den adgangskode, der er inkluderet i anmodningen, er korrekte"}

Det fejl felt skal ikke matche svarkoden. I stedet skal det være en fejlkode, der er unik for vores applikation. Generelt er der ingen konvention for fejl felt, forvent at det er unikt.

Normalt indeholder dette felt kun alfanumerik og forbundne tegn, såsom bindestreger eller understregninger. For eksempel, 0001, auth-0001og forkert brugerpas er kanoniske eksempler på fejlkoder.

Det besked del af kroppen betragtes normalt som præsentabel på brugergrænseflader. Derfor bør vi oversætte denne titel, hvis vi støtter internationalisering. Så hvis en klient sender en anmodning med en Accept-sprog header svarende til fransk, den titel værdi skal oversættes til fransk.

Det detalje delen er beregnet til brug af klientudviklere og ikke slutbrugeren, så oversættelsen er ikke nødvendig.

Derudover kunne vi også angive en URL - som f.eks Hjælp felt - som klienter kan følge for at finde flere oplysninger:

{"error": "auth-0001", "message": "Forkert brugernavn og adgangskode", "detail": "Sørg for, at brugernavnet og adgangskoden, der er inkluderet i anmodningen, er korrekte", "help": "// eksempel. com / hjælp / fejl / auth-0001 "}

Sommetider, Vi vil muligvis rapportere mere end en fejl til en anmodning. I dette tilfælde skal vi returnere fejlene i en liste:

{"fejl": [{"fejl": "auth-0001", "message": "Forkert brugernavn og adgangskode", "detalje": "Sørg for, at brugernavnet og adgangskoden, der er inkluderet i anmodningen, er korrekte", "hjælp" : "//eksempel.com/hjælp/fejl/auth-0001"}, ...]}

Og når der opstår en enkelt fejl, svarer vi med en liste, der indeholder et element. Bemærk, at det at reagere med flere fejl kan være for kompliceret til enkle applikationer. I mange tilfælde er det tilstrækkeligt at reagere med den første eller mest betydningsfulde fejl.

3.4. Standardiserede reaktionsorganer

Mens de fleste REST API'er følger lignende konventioner, varierer specifikationer normalt, herunder navnene på felterne og informationen, der er inkluderet i responsorganet. Disse forskelle gør det vanskeligt for biblioteker og rammer at håndtere fejl ensartet.

I et forsøg på at standardisere REST API-fejlhåndtering, IETF udtænkte RFC 7807, som skaber et generelt skema til fejlhåndtering.

Dette skema består af fem dele:

  1. type - En URI-identifikator, der kategoriserer fejlen
  2. titel - En kort, menneskelig læsbar besked om fejlen
  3. status - HTTP-svarkoden (valgfri)
  4. detalje - En menneskelig læsbar forklaring på fejlen
  5. eksempel - En URI, der identificerer den specifikke forekomst af fejlen

I stedet for at bruge vores brugerdefinerede fejlrespons-organ kan vi konvertere vores krop til:

{"type": "/ fejl / forkert brugerpas", "title": "Forkert brugernavn eller adgangskode.", "status": 401, "detail": "Godkendelse mislykkedes på grund af forkert brugernavn eller adgangskode.", "forekomst": "/ login / log / abc123"}

Bemærk, at type felt kategoriserer typen af ​​fejl, mens eksempel identificerer en bestemt forekomst af fejlen på en lignende måde som henholdsvis klasser og objekter.

Ved at bruge URI'er kan klienter følge disse stier for at finde flere oplysninger om fejlen på samme måde som HATEOAS-links kan bruges til at navigere i en REST API.

Overholdelse af RFC 7807 er valgfri, men det er fordelagtigt, hvis ensartethed ønskes.

4. Eksempler

Ovenstående praksis er almindelig i nogle af de mest populære REST API'er. Mens de specifikke navne på felter eller formater kan variere mellem websteder, de generelle mønstre er næsten universelle.

4.1. Twitter

Lad os for eksempel sende en GET-anmodning uden at levere de krævede godkendelsesdata:

krølle -X GET //api.twitter.com/1.1/statuses/update.json?include_entities=true

Twitter API reagerer med en fejl med følgende instans:

{"fejl": [{"code": 215, "message": "Dårlig godkendelsesdata." }]}

Dette svar inkluderer en liste, der indeholder en enkelt fejl med dens fejlkode og meddelelse. I Twitters tilfælde er der ingen detaljeret meddelelse til stede, og en generel fejl - snarere end en mere specifik 401-fejl - bruges til at angive, at godkendelse mislykkedes.

Nogle gange er en mere generel statuskode lettere at implementere, som vi vil se i vores forårsexempel nedenfor. Det giver udviklere mulighed for at fange grupper af undtagelser og ikke differentiere den statuskode, der skal returneres. Når det er muligt, dog den mest specifikke statuskode skal bruges.

4.2. Facebook

I lighed med Twitter inkluderer Facebooks Graph REST API også detaljerede oplysninger i sine svar.

Lad os f.eks. Udføre en POST-anmodning om godkendelse med Facebook Graph API:

krølle -X GET //graph.facebook.com/oauth/access_token?client_id=foo&client_secret=bar&grant_type=baz

Vi modtager følgende fejl:

{"error": {"message": "Manglende redirect_uri-parameter.", "type": "OAuthException", "code": 191, "fbtrace_id": "AWswcVwbcqfgrSgjG80MtqJ"}}

Ligesom Twitter bruger Facebook også en generisk fejl - snarere end en mere specifik 400-niveau-fejl - for at betegne en fiasko. Ud over en besked og en numerisk kode inkluderer Facebook også en type felt, der kategoriserer fejlen og et sporings-ID (fbtrace_id), der fungerer som en intern supportidentifikator.

5. Konklusion

I denne artikel undersøgte vi nogle af de bedste fremgangsmåder til REST API-fejlhåndtering, herunder:

  • Tilvejebringelse af specifikke statuskoder
  • Med yderligere oplysninger i reaktionsorganer
  • Håndtering af undtagelser på en ensartet måde

Mens detaljerne i fejlhåndtering vil variere efter applikation, disse generelle principper gælder for næsten alle REST API'er og skal følges, når det er muligt.

Dette tillader ikke kun klienter at håndtere fejl på en ensartet måde, men det forenkler også den kode, vi opretter, når vi implementerer en REST API.

Koden, der henvises til i denne artikel, er tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found