=

RESTful chybové struktury v .NET 6

Vracet chybové struktury v .NET 6 je jednoduché. Háček je jen v tom, že různé verze frameworku se historicky chovaly odlišně a v současné době existuje více možností, jak chybu z API vrátit. V článku vysvětlím pár základních tipů, kterých se stačí držet.

Chybovou strukturu je nutné vrátit pokaždé, když HTTP požadavek neskončí úspěšně. Jedná se tedy o chybové stavy 4xx a 5xx. Všechny chybové stavy by měly vracet vždy stejnou strukturu, aby ji klient mohl snadno zparsovat. Podobu chybových struktur definuje RFC 7807.

Více podrobností popisuji v mém průvodci REST API.

Chybové struktury v .NETu

Vývojáři implementovali zmíněné RFC a vytvořily v .NETu hned 3 chybové struktury, které lze použít:

ProblemDetails
ValidationProblemDetails : ProblemDetails
HttpValidationProblemDetails : ProblemDetails

Zmíněný ProblemDetails implementuje RFC 7807, tedy základní potřebné vlastnosti chybové struktury. Dle tohoto RFC je strukturu možné dále rozšiřovat o libovolné další properties nebo objekty. Přesně to dělají poděděné ValidationProblemDetails a HttpValidationProblemDetails.

ValidationProblemDetails a HttpValidationProblemDetails navíc obsahují objekt errors a jsou tedy vhodné pro validační chyby. Pro validační chyby se používají stavové kody 400 a 422. Osobně bych se doporučil držet pouze stavového kódu 400, protože 422 byl navržen pro jiný specifický účel a ne každý systém (natož vývojář) mu rozumí.

ValidationProblemDetails a HttpValidationProblemDetails se liší pouze v tom, že ValidationProblemDetails podporují ModelState, ze kterého vzniká objekt errors. Vznik HttpValidationProblemDetails (od .NET 6) považuji za zbytečný, nehledě na to, že nemají ani podporu ve statické třídě Results, která se používá pro .NET 6 Minimal APIs.

Generování chyb

Vrátit (Validation)ProblemDetails lze z .NET 6 dvěma způsoby.

  1. explicitně naplníme Response Body instancí jedné z výše zmíněných tříd
  2. provoláme nějakou framework metodu, která vytvoří instanci zmíněných tříd implicitně

Prakticky na všech mých přednáškách doporučuji naprogramovat si jedno místo, které chybové struktury generuje (tedy varianta 1). Já to řeším tak, že nezpracovatelný požadavek ukončím vyhozením vybrané výjimky. Následně mám jeden ExceptionMiddleware, který různé chyby vyhodnocuje a generuje vhodnou chybovou strukturu. Používám ProblemDetails v kombinaci s ValidationProblemDetails a nebo pouze ProblemDetails. Ty lze totiž snadno rozšířit o libovolný errors objekt. Funguje to takto:

var p = new ProblemDetails();
p.Title = "Validation Failed";
p.Status = 400;
p.Extensions.Add("Errors", new
{
    Property1 = "error ab",
    Property2 = "error xy"
});

A výsledek je:

{
  "title": "Validation Failed",
  "status": 400,
  "errors": {
    "property1": "error ab",
    "property2": "error xy"
  }
}

Druhá možnost je vracet chyby z různých míst v kódu s využitím frameworkových metod. Obvykle se tedy jedná o MVC:

public IActionResult Demo()
{
    return Problem();
}

nebo o Minimal APIs:

app.MapGet("/", () =>
{
    return Results.Problem();
});

Zde je ale větší riziko, že API bude vracet polovičatou odpověď. Zejména je nutné dát si pozor na použití metod typu BadRequest() nebo BadRequest(ModelState). První vygeneruje pěknou strukturu:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "traceId": "00-bd0b009f94fd15f705dd7f9864fdabe3-602fe24ae23b5a61-00"
}

zatímco druhá možnost s ModelState (ve kterém je jedna chyba) vrátí:

{
  "": [
    "An error occured!"
  ]
}

Shrnutí

  • chyby vracíme vždy, když dojde ke stavu 4xx, 5xx
  • dodržujeme jednotnou chybovou strukturu dle RFC 7807
  • v případě validačních chyb používáme status code 400 (Bad Request)
  • nepoužíváme novou třídu HttpValidationProblemDetails
  • lepší je generovat chyby na jednom místě (middleware)
  • při použití frameworkových metod je nutné hlídat vrácené struktury
Miroslav Holec

Miroslav Holec

6. 5. 2022


Videa

RestApi.CZ

Právě jsem spustil průvodce Designem REST API

📖 Přečíst restapi.cz

Veřejná školení Místo Datum Délka Cena bez DPH Poznámky
Novinky v .NET 6 a C# 10 online 13. 10. 2022 1 den 3 900 Kč poslední šance registrovat
Vývoj aplikací v ASP.NET Core Praha + online 11/2022 1 den 4 900 Kč bestseller registrovat
Blazor Server & WebAssembly Praha + online 11/2022 2 dny 10 900 Kč registrovat
ASP.NET Core gRPC Praha + online 11/2022 1 den 4 900 Kč registrovat
Design REST API a Design First Praha + online 11/2022 2 dny 9 900 Kč exkluzivní registrovat
Vývoj REST API s Minimal APIs Praha + online 11/2022 1 den 5 900 Kč exkluzivní registrovat
Vývoj REST API v .NET MVC Praha + online 11/2022 1 den 4 900 Kč bestseller registrovat
Entity Framework Core Praha + online 11/2022 2 dny 11 900 Kč registrovat
Vývoj .NET aplikací pro Azure Praha + online 11/2022 1 den 5 900 Kč nový registrovat

kontakt zde

Dotazy, poptávky a objednávky

mirek@miroslavholec.cz
Loading