0Pricing
C# Academy · Lezione

Creazione della prima Minimal API

Avvii un progetto Minimal API, definisca i gestori delle route e restituisca risultati tipizzati con il minimo codice necessario.

Creazione della prima Minimal API è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Che cosa sono le Minimal API?

Le Minimal API, introdotte in .NET 6, consentono di creare endpoint HTTP con il minimo codice infrastrutturale: niente controller né attributi delle azioni, ma solo gestori delle route definiti direttamente in Program.cs. Sono ideali per i microservizi e le API leggere.

La Minimal API più semplice

Un'API HTTP completa in poche righe. I metodi MapGet, MapPost, MapPut e MapDelete definiscono i gestori delle route per ogni verbo HTTP.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello, Minimal API!");
app.MapGet("/ping", () => Results.Ok(new { status = "pong" }));

app.Run();
// That's it — no Startup.cs, no controllers

Risultati tipizzati per risposte HTTP corrette

Utilizzi Results o TypedResults per codici di stato HTTP e tipi di contenuto corretti. TypedResults è preferibile per l'inferenza dello schema OpenAPI.

app.MapGet("/products/{id}", async (int id, AppDbContext db) =>
{
    var product = await db.Products.FindAsync(id);
    return product is null
        ? Results.NotFound()
        : Results.Ok(product);
});

app.MapPost("/products", async (Product product, AppDbContext db) =>
{
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Results.Created($"/products/{product.Id}", product);
});

Parametri delle route e stringhe di query

I parametri delle route vengono acquisiti dal percorso dell'URL, i parametri della stringa di query vengono associati automaticamente dalla query e il corpo della richiesta viene deserializzato da JSON.

// Route param {id} + query param ?includeDeleted
app.MapGet("/orders/{id}", async (
    int id,
    bool includeDeleted = false,
    AppDbContext db) =>
{
    var query = db.Orders.AsQueryable();
    if (!includeDeleted) query = query.Where(o => !o.IsDeleted);
    var order = await query.FirstOrDefaultAsync(o => o.Id == id);
    return order is null ? Results.NotFound() : Results.Ok(order);
});

Iniezione delle dipendenze nei gestori delle route

I servizi registrati nel contenitore DI possono essere iniettati direttamente come parametri dei gestori delle route. Il framework li risolve automaticamente.

builder.Services.AddScoped<ProductService>();

app.MapGet("/products", async (ProductService svc) =>
{
    var products = await svc.GetAllAsync();
    return Results.Ok(products);
});

app.MapDelete("/products/{id}", async (int id, ProductService svc) =>
{
    var deleted = await svc.DeleteAsync(id);
    return deleted ? Results.NoContent() : Results.NotFound();
});

Binding del corpo della richiesta

I parametri che corrispondono a servizi registrati vengono iniettati; tutto il resto viene associato al corpo della richiesta (JSON per impostazione predefinita). Utilizzi [FromBody] esplicitamente, se necessario.

record CreateProductRequest(string Name, decimal Price, int Stock);

app.MapPost("/products", async (
    CreateProductRequest req,
    ProductService svc) =>
{
    var product = await svc.CreateAsync(req.Name, req.Price, req.Stock);
    return TypedResults.Created($"/products/{product.Id}", product);
});

Restituire codici di stato diversi

Results fornisce metodi factory per tutte le risposte HTTP comuni. Li utilizzi per creare API REST semanticamente corrette.

app.MapPut("/products/{id}", async (int id, Product update, AppDbContext db) =>
{
    var existing = await db.Products.FindAsync(id);
    if (existing is null) return Results.NotFound();

    existing.Name  = update.Name;
    existing.Price = update.Price;
    await db.SaveChangesAsync();
    return Results.Ok(existing);
});

// Other useful Results:
// Results.BadRequest("message")
// Results.Conflict()
// Results.UnprocessableEntity(errors)
// Results.Accepted()

Aggiungere metadati con WithName e WithTags

Alleghi metadati agli endpoint per migliorare la documentazione e il routing. Utilizzi WithName, WithTags e WithSummary per organizzare l'output OpenAPI.

app.MapGet("/products/{id}", GetProduct)
   .WithName("GetProductById")
   .WithTags("Products")
   .WithSummary("Retrieves a product by its ID")
   .Produces<Product>()
   .Produces(404);

static async Task<IResult> GetProduct(int id, AppDbContext db)
{
    var p = await db.Products.FindAsync(id);
    return p is null ? Results.NotFound() : Results.Ok(p);
}

Autorizzazione nelle Minimal API

Applichi RequireAuthorization() per proteggere gli endpoint oppure utilizzi AllowAnonymous() per escluderli. I criteri funzionano come nei controller.

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();

app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/profile", (ClaimsPrincipal user) =>
    Results.Ok(user.Identity!.Name))
   .RequireAuthorization();

app.MapGet("/public", () => "No auth needed")
   .AllowAnonymous();

Organizzare con metodi statici

Per API più grandi, sposti i gestori delle route in metodi statici o metodi di estensione, così da mantenere Program.cs ordinato e facile da consultare.

// Extension method groups endpoints by feature
public static class ProductEndpoints
{
    public static void MapProductEndpoints(this WebApplication app)
    {
        app.MapGet("/products",    GetAll);
        app.MapGet("/products/{id}", GetById);
        app.MapPost("/products",   Create);
    }

    private static async Task<IResult> GetAll(AppDbContext db)
        => Results.Ok(await db.Products.AsNoTracking().ToListAsync());

    // ... other handlers
}

// In Program.cs:
app.MapProductEndpoints();

Esempio reale: Minimal API CRUD completa

Una Minimal API CRUD completa per una risorsa Todo — concisa, verificabile e pronta per la produzione.

app.MapGet("/todos", async (AppDbContext db) =>
    Results.Ok(await db.Todos.AsNoTracking().ToListAsync()));

app.MapGet("/todos/{id}", async (int id, AppDbContext db) =>
{
    var todo = await db.Todos.FindAsync(id);
    return todo is null ? Results.NotFound() : Results.Ok(todo);
});

app.MapPost("/todos", async (Todo todo, AppDbContext db) =>
{
    db.Todos.Add(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/todos/{todo.Id}", todo);
});

app.MapDelete("/todos/{id}", async (int id, AppDbContext db) =>
{
    int n = await db.Todos.Where(t => t.Id == id).ExecuteDeleteAsync();
    return n > 0 ? Results.NoContent() : Results.NotFound();
});

Verifica rapida

In che modo un gestore di route di una Minimal API riceve un servizio DI registrato?

Riepilogo: creare la prima Minimal API

Punti chiave:

  • MapGet/Post/Put/Delete definiscono direttamente i gestori delle route in Program.cs
  • Utilizzi Results / TypedResults per i codici di stato HTTP corretti
  • I parametri di route, query string, body e DI vengono tutti associati automaticamente
  • Utilizzi RequireAuthorization() e AllowAnonymous() per l'autenticazione
  • Organizzi le API più grandi con metodi di estensione o gruppi di route

Domande Frequenti

La lezione «Creazione della prima Minimal API» è gratuita?

Sì — il testo completo di «Creazione della prima Minimal API» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Creazione della prima Minimal API»?

Avvii un progetto Minimal API, definisca i gestori delle route e restituisca risultati tipizzati con il minimo codice necessario. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Creazione della prima Minimal API»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Creazione della prima Minimal API
  2. Gruppi di route, parametri e convalida
  3. Middleware e filtri nelle Minimal API
  4. OpenAPI, versionamento e distribuzione
← Torna a C# Academy