0Pricing
C# Academy · Aula

Criando sua primeira Minimal API

Inicie um projeto de Minimal API, defina manipuladores de rotas e retorne resultados tipados com o mínimo de código auxiliar.

Criando sua primeira Minimal API é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

O que são APIs mínimas?

As APIs mínimas, introduzidas no .NET 6, permitem criar pontos de acesso HTTP com pouca configuração repetitiva — sem controladores, sem atributos de ação, apenas manipuladores de rotas definidos diretamente em Program.cs. Elas são ideais para microsserviços e APIs leves.

A API mínima mais simples

Uma API HTTP completa em apenas algumas linhas. Os métodos MapGet, MapPost, MapPut e MapDelete definem os manipuladores de rotas para cada 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

Resultados tipados para respostas HTTP adequadas

Use Results ou TypedResults para obter códigos de status HTTP e tipos de conteúdo corretos. TypedResults é preferível para a inferência de esquemas do 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);
});

Parâmetros de rota e cadeias de consulta

Os parâmetros de rota são capturados do caminho da URL, os parâmetros da cadeia de consulta são vinculados automaticamente a partir da consulta e o corpo da requisição é desserializado do 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);
});

Injeção de dependências nos manipuladores de rotas

Os serviços registrados no contêiner de DI podem ser injetados diretamente como parâmetros dos manipuladores de rotas. A estrutura os resolve 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();
});

Vinculação do corpo da requisição

Os parâmetros correspondentes a serviços registrados são injetados; todo o restante é vinculado ao corpo da requisição (JSON por padrão). Use [FromBody] explicitamente, se necessário.

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);
});

Retornando códigos de status diferentes

Results fornece métodos de fábrica para todas as respostas HTTP comuns. Use-os para criar APIs REST semanticamente corretas.

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()

Adicionando metadados com WithName e WithTags

Anexe metadados aos pontos de acesso para melhorar a documentação e o roteamento. Use WithName, WithTags e WithSummary para obter uma saída OpenAPI organizada.

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);
}

Autorização em APIs mínimas

Aplique RequireAuthorization() para proteger os pontos de acesso ou use AllowAnonymous() para dispensar essa proteção. As políticas funcionam da mesma forma que nos controladores.

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();

Organização com Métodos Estáticos

Para APIs maiores, mova os manipuladores de rotas para métodos estáticos ou métodos de extensão para manter Program.cs limpo e fácil de navegar.

// 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();

API Minimalista Completa de CRUD

Uma API Minimalista completa de CRUD para um recurso de tarefas — concisa, testável e pronta para produção.

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ção Rápida

Como o manipulador de rota de uma API Minimalista recebe um serviço DI registrado?

Resumo: Criando Sua Primeira API Minimalista

Principais conclusões:

  • MapGet/Post/Put/Delete definem diretamente os manipuladores de rotas em Program.cs
  • Use Results / TypedResults para obter códigos de status HTTP corretos
  • Parâmetros de rota, consulta, corpo e DI são associados automaticamente
  • Use RequireAuthorization() e AllowAnonymous() para autenticação
  • Organize APIs grandes com métodos de extensão ou grupos de rotas

Perguntas Frequentes

A aula “Criando sua primeira Minimal API” é grátis?

Sim — o texto completo de “Criando sua primeira Minimal API” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Criando sua primeira Minimal API”?

Inicie um projeto de Minimal API, defina manipuladores de rotas e retorne resultados tipados com o mínimo de código auxiliar. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Criando sua primeira Minimal API”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Criando sua primeira Minimal API
  2. Grupos de rotas, parâmetros e validação
  3. Middleware e filtros em Minimal APIs
  4. OpenAPI, versionamento e implantação
← Voltar para C# Academy