← Stack web // stack web · back end · linguagem e plataforma

C#: sua primeira API com .NET

C# é a linguagem. .NET é a plataforma que compila esse código e executa ele, e que já traz dentro o servidor HTTP, o gerenciador de pacotes e a linha de comando. Você instala uma coisa só e sai com uma API respondendo.

O que o C# resolve

Código de servidor atende muita gente ao mesmo tempo e quebra caro. Quando alguém escreve Total onde o resto do sistema escreve total, numa linguagem sem checagem de tipo esse erro aparece na hora em que o cliente clica, em produção, de madrugada. O C# recusa antes: o compilador para, aponta o arquivo e a linha, e o programa nem chega a subir.

A segunda dor é de equipe. Código de back end vive anos e passa por gente que nunca conversou com quem escreveu a primeira versão. Tipo declarado na assinatura do método é documentação que a máquina cobra, e ela continua verdadeira depois de cem alterações feitas por outras pessoas.

Os conceitos que você precisa antes da primeira linha

  • C# e .NET são coisas diferentes. C# é a linguagem que você escreve. .NET é a plataforma que roda o resultado, com o runtime, as bibliotecas e as ferramentas. A mesma plataforma roda outras linguagens, e C# é a mais usada nela.
  • SDK e runtime. O runtime só executa programa pronto. O SDK traz o compilador, os templates e o comando dotnet. Pra escrever código você instala o SDK, que já inclui o runtime.
  • Compilar vem antes de rodar. Seu código vira um formato intermediário, e o runtime executa esse formato. Isso explica por que o erro de tipo aparece no terminal em vez de aparecer no cliente, e por que existe um passo de build no meio do caminho.
  • Projeto e arquivo .csproj. Uma pasta com .csproj dentro é um projeto. Esse arquivo diz qual versão do .NET você mira e quais pacotes entram. O comando dotnet run lê ele pra saber o que compilar.
  • ASP.NET Core e Minimal API. ASP.NET Core é a parte do .NET que fala HTTP, com um servidor embutido chamado Kestrel. Minimal API é o jeito curto de declarar rota: uma linha liga um caminho a uma função que devolve a resposta.

A linguagem por dentro: tipos, classes e objetos

C# tem tipagem estática com inferência: todo valor tem tipo fixo conferido pelo compilador, e o var só poupa você de escrever o que o compilador já deduziu. É o mesmo espírito do Java com a cerimônia aparada.

  • Tipos de valor e de referência: int, double, bool e decimal carregam o próprio valor. string, listas e as suas classes carregam uma referência ao objeto. O decimal merece destaque: é o tipo para dinheiro, sem os arredondamentos binários do double.
  • Coleções com generics: List<int> e Dictionary<string, Produto> dizem ao compilador o que mora dentro, e ele barra o que não pertence.
  • Orientação a objetos: classe, construtor, herança e interface, como no Java, mais duas comodidades da casa: propriedades (get; set; no lugar de getter e setter escritos à mão) e records pra dados imutáveis comparados por valor.
// tipos, propriedade e objeto em doze linhas
var precos = new List<decimal> { 12.5m, 30m, 7m };
decimal total = precos.Sum();           // LINQ: consulta em coleção

var c = new Carrinho();
c.Add("caderno");
Console.WriteLine($"R$ {total:F2}");    // interpolação de string

class Carrinho
{
    public List<string> Itens { get; } = new();   // propriedade
    public void Add(string item) => Itens.Add(item);
}

O precos.Sum() vem do LINQ, a biblioteca de consulta embutida: filtrar, somar e ordenar coleção sem escrever laço é rotina em C#.

Hello world: uma API que responde em localhost

Tudo aqui roda pelo terminal, em Linux, macOS ou Windows. Nenhuma IDE é obrigatória, e qualquer editor de texto serve pra alterar o arquivo do passo 3.

  1. Instale o SDK do .NET pela página oficial de download, escolhendo a linha .NET 10.0, que é a versão de suporte longo em vigor. Feche e abra o terminal, e confira:

    dotnet --version

    A resposta tem que ser um número de versão começando em 10. Se o terminal disser que o comando não existe, o SDK não entrou no PATH e vale reabrir o terminal antes de qualquer outra coisa.

  2. Crie o projeto. O nome curto do template ASP.NET Core vazio é web, e -o define a pasta:

    dotnet new web -o OlaApi --no-https
  3. Entre na pasta e abra o arquivo Program.cs:

    cd OlaApi

    O template escreveu isto, e é o programa inteiro:

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
  4. Troque o conteúdo do Program.cs por este, que muda o texto da raiz e acrescenta uma segunda rota:

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.MapGet("/", () => "Olá, mundo");
    app.MapGet("/ping", () => "pong");
    
    app.Run();

    Salve o arquivo.

  5. Suba o servidor, fixando a porta pra você saber de antemão o endereço:

    dotnet run --urls "http://localhost:5080"

    Esse comando sozinho baixa as dependências, compila o projeto e sobe o servidor. Não existe passo de build separado pra fazer na mão.

  6. Com o servidor de pé, abra http://localhost:5080 no navegador. Pra conferir a outra rota sem sair do terminal, use uma segunda janela:

    curl http://localhost:5080/ping
  7. Pra encerrar, volte na janela do servidor e aperte Ctrl + C.

A prova de que funcionou. Duas coisas ao mesmo tempo. No terminal, depois das linhas de compilação, aparece Now listening on: http://localhost:5080 e o cursor fica parado, sem devolver o prompt. Esse prompt travado é o sinal certo: o processo está de pé, esperando pedido. No navegador, http://localhost:5080 mostra Olá, mundo em texto cru, sem HTML nenhum em volta, e http://localhost:5080/ping mostra pong. Um caminho que você não declarou, como /qualquer, devolve status 404 com o corpo vazio, e isso também é prova: o roteamento está funcionando e sabe o que não existe. No navegador essa resposta vazia aparece como página em branco ou como a tela de erro do próprio navegador. Se o navegador acusar falha de conexão, olhe o terminal. Com a porta 5080 já ocupada por outro programa, o .NET reclama na hora de subir e o processo morre em vez de ficar esperando. Troque o número no --urls e rode de novo.

O que o C# não é

O mito que mais atrapalha quem está começando: "C# só roda em Windows, dentro do Visual Studio, e precisa de licença paga". Isso descrevia o .NET Framework antigo, que era mesmo exclusivo do Windows. O .NET de hoje roda em Linux, macOS e Windows, tem código-fonte e binários sob licença MIT, e o passo a passo acima foi escrito pra terminal justamente por isso. Nada aqui depende de IDE.

Sobra uma segunda confusão, a do nome. O C em C# faz muita gente achar que a linguagem tem a ver com C ou C++, e o parentesco fica só na aparência da sintaxe. O programa em C# roda sobre um runtime com coletor de lixo, que devolve a memória sozinho. Você não aloca nem libera nada na mão.

Fontes

Rodamos esse passo a passo numa máquina Linux em 15/08/2026, com o SDK .NET 8.0.422 no lugar da linha 10.0 que a página indica. Os comandos dotnet new web -o OlaApi --no-https e dotnet run --urls "http://localhost:5080" funcionaram exatamente como estão escritos, e o terminal imprimiu Now listening on: http://localhost:5080. O curl na raiz devolveu HTTP/1.1 200 OK com Content-Type: text/plain; charset=utf-8 e o corpo Olá, mundo, a rota /ping devolveu 200 com pong, e o caminho /qualquer devolveu 404 com Content-Length: 0.

Para continuar

Do lado do back end, a linguagem é escolha. Node.js resolve o mesmo problema aproveitando o JavaScript que você já usa no navegador. Java segue o mesmo caminho de compilar antes de rodar, com outra sintaxe e outra ferramenta de build. As três estão lado a lado no mapa da stack web, junto do resto do caminho.

O curso desta trilha está em preparação. A lista paga menos.

Os tutoriais daqui continuam gratuitos. O que está a caminho é um curso pago que transforma esse mapa em formação guiada, na ordem certa e com projeto. Deixe seu e-mail: você recebe os estudos novos gratuitos e, no lançamento, o desconto de quem entrou na lista primeiro.