Controller
Trebuie clarificat în primul rând cum funcționează aplicația de backend în .NET. Când aplicația de tip WebApplication este pornită, se deschide un port și se așteaptă cererile HTTP. Cererea este parsată și transformată într-un context HTTP. Contextul este trimis către un pipeline de execuție care va apela rutinele adecvate pentru acea cerere și va întoarce răspunsul înapoi în acel pipeline. Fiecare pas executat în pipeline se numește middleware, iar o parte din acestea se pot defini de către dezvoltatori. Ultimul middleware executat la tratarea cererii apelează clase definite de dezvoltator de tip controller. În controller se specifică ce endpoint-uri/rute din API-ul serverului corespund la ce metode din acea clasă. O clasă controller este o clasă specială ai cărei metode publice sunt apelate la accesul rutelor corespunzătoare metodei, acestea moștenesc clasa ControllerBase. Pentru ca framework-ul să identifice controllerele și rutele, se decorează clasa și metodele cu atribute, clase ce extind clasa Attibute. De exemplu, [ApiController] care decorează o clasă controller specifică framework-ului că această clasă trebuie să fie folosită ca controller; [Route("api/[controller]")] pus pe clasă și [HttpGet("my-route")] pe metoda din controller specifică că atunci când se accesează ruta "/api/<nume_clasa_controller>/my-route" cu un HTTP GET se apelează acea metodă în cauză.
Decorarea claselor și metodelor cu atribute, sau în Java cu adnotări, pentru ca acestea să dobândească mai multe funcționalități, la runtime sau compiletime, este un caz de @OP (attribute-oriented programming).
În cereri HTTP, datele transmise către server pot fi specificate în mai multe locații din cerere care pot fi extrase și pasate automat ca parametri pentru metoda din controller corespunzătoare rutei. Aceste locații se specifică folosind atribute în fața parametrilor în următoarele moduri:
- Pentru parametri specificați într-o rută, ca de exemplu "api/{type}/user/{id:guid}", se poate vedea descrisă mai jos. Se poate vedea și că se pot pune constrângeri ca parametrul "id" să fie formatat ca fiind un Guid și să se întoarcă automat cod de BadRequest către client dacă șirul este în formatul greșit.
[HttpGet("api/{type}/user/{id:guid}")]
public Task<IActionResult> MyMethod([FromRoute] string type, [FromRoute] Guid id);