.NET
Ce que j'ai appris sur la construction de REST API en .NET
Une API CRUD toute simple, pas de paiements, rien de sophistiqué. Les HTTP verbs, le routing, EF Core, et les status codes qui font enfin tilt en la construisant.
Je viens de terminer ma première vraie REST API en .NET : une app CRUD toute simple, pas de paiements, rien de sophistiqué. C'est basique, mais la construire, c'est là que pas mal de fondamentaux font enfin tilt pour moi.
Faire correspondre les HTTP verbs à ce qu'ils sont censés faire
Je savais que GET, POST, PUT, et DELETE existaient avant de commencer ça, mais je ne comprenais pas vraiment pourquoi ça comptait lequel on utilisait avant d'avoir construit quelque chose avec les quatre. GET lit, POST crée, PUT met à jour, DELETE supprime, et chacun se mappe proprement sur une action de Controller. Les voir côte à côte, ça arrête d'être une règle abstraite et ça devient évident.
Routing et Controllers
J'utilise des Controllers parce que c'est ce qu'utilise chaque tutoriel que j'ai suivi. [ApiController], [Route("api/products")], et une action par HTTP verb :
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
private readonly AppDbContext _context;
public ProductsController(AppDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> GetAll()
{
var products = await _context.Products.ToListAsync();
return Ok(products);
}
}
Ça avait l'air de beaucoup d'attributes à mémoriser au début, mais une fois que j'ai compris que la route et le verb ensemble décident quelle action s'exécute, ça arrête de sembler arbitraire.
Parler au database avec EF Core
C'est la première fois que j'utilise Entity Framework Core pour quelque chose de réel plutôt que l'exemple jouet d'un tutoriel. Un model, un DbContext, et une connection string :
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<Product> Products => Set<Product>();
}
Puis exécuter la migration pour vraiment créer la table :
dotnet ef migrations add InitialCreate
dotnet ef database update
C'était la première fois que l'API semblait faire quelque chose au lieu de juste renvoyer de fausses données.
Les status codes veulent vraiment dire quelque chose
Avant ça, j'aurais renvoyé 200 pour à peu près tout. Construire cette API, c'est la première fois que je fais attention à celui que je renvoie vraiment :
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
var product = await _context.Products.FindAsync(id);
if (product is null)
{
return NotFound();
}
return Ok(product);
}
[HttpPost]
public async Task<IActionResult> Create(Product product)
{
_context.Products.Add(product);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
}
NotFound() donne un 404, Ok() un 200, et CreatedAtAction renvoie un 201 avec l'URL de la chose qui vient d'être créée. Bien les choisir rend l'API compréhensible pour quiconque l'appelle sans avoir à lire le code.
Où ça m'en laisse
Rien dans ce projet n'est avancé. C'est une API CRUD toute simple avec un database derrière, et l'essentiel de ce que j'ai appris, c'est juste les fondamentaux qui s'emboîtent pour la première fois. C'est tout ce que c'est pour l'instant, et c'est suffisant pour là où j'en suis.