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 controllersResultados 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/TypedResultspara obter códigos de status HTTP corretos - Parâmetros de rota, consulta, corpo e DI são associados automaticamente
- Use
RequireAuthorization()eAllowAnonymous()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
- Criando sua primeira Minimal API
- Grupos de rotas, parâmetros e validação
- Middleware e filtros em Minimal APIs
- OpenAPI, versionamento e implantação