Primeiros passos

July 11, 2026 · View on GitHub

Leia em English ou Português (BR).

Esta página leva você de um projeto em branco até um servidor Horse rodando em menos de cinco minutos. Assume que você tem Delphi 10.4 ou mais recente (ou Lazarus 2.2 / FPC 3.2+) e conexão com a internet para o Boss baixar dependências.

Se algo abaixo não se aplicar ao seu ambiente, consulte primeiro Suporte de Compilador.


1. Instalar o Boss

O Boss é o gerenciador de pacotes que o Horse usa para distribuição. Instalação única:

# Windows (PowerShell, como administrador)
iwr https://github.com/HashLoad/boss/releases/latest/download/boss-windows.exe -OutFile boss.exe
Move-Item boss.exe C:\Windows\System32\

# Linux / macOS
curl -L https://github.com/HashLoad/boss/releases/latest/download/boss-linux -o boss
chmod +x boss
sudo mv boss /usr/local/bin/

Verifique:

boss --version

2. Criar o projeto e adicionar o Horse

Crie uma nova aplicação console em Delphi (ou um projeto Lazarus), salve e, num terminal aberto no diretório do projeto:

boss init -q                  # gera um boss.json
boss install horse            # adiciona o Horse ao search path do projeto

O Boss baixa a versão estável mais recente do Horse, coloca em modules/horse/ e adiciona o caminho ao seu .dproj / .lpi automaticamente. Agora você pode usar uses Horse; em qualquer unidade.

3. Servidor mínimo — Delphi

program HelloHorse;

{$APPTYPE CONSOLE}

uses
  Horse;

begin
  THorse.Get('/ping',
    procedure(Req: THorseRequest; Res: THorseResponse)
    begin
      Res.Send('pong');
    end);

  WriteLn('Escutando em http://127.0.0.1:9000/ping');
  THorse.Listen(9000);
end.

Compile, execute e em outro terminal:

curl http://127.0.0.1:9000/ping
# pong

Pronto. Ctrl-C para parar.

4. Servidor mínimo — Lazarus / FPC

program HelloHorse;

{$MODE DELPHI}{$H+}

uses
  Horse;

procedure GetPing(Req: THorseRequest; Res: THorseResponse);
begin
  Res.Send('pong');
end;

begin
  THorse.Get('/ping', @GetPing);
  THorse.Listen(9000);
end.

Dois pontos importantes para FPC:

  • {$MODE DELPHI}{$H+} é obrigatório para que procedimentos anônimos e a semântica string = AnsiString correspondam ao Delphi.
  • Callbacks de rota usam @ porque o Lazarus distingue valor de procedimento de referência a procedimento.

5. Convenções de estrutura de projeto

Você não é obrigado a seguir — o Horse não impõe layout — mas os exemplos oficiais usam:

meu-servidor/
├── boss.json                ← manifesto do Boss
├── boss-lock.json           ← versões fixadas (auto-gerado)
├── modules/                 ← dependências instaladas pelo Boss (gitignored)
├── src/
│   ├── HelloHorse.dpr       ← entry point (registra rotas, chama Listen)
│   ├── Controllers/         ← uma unit por recurso (Users, Products, ...)
│   ├── Services/            ← regra de negócio, sem dependência do Horse
│   └── Middlewares/         ← preocupações transversais
└── tests/
    └── ...

Um entry point típico compõe a aplicação:

uses
  Horse, Horse.Jhonson, Horse.CORS,
  Controllers.Users, Controllers.Products;

begin
  THorse
    .Use(Jhonson)                 // parsing de body JSON
    .Use(CORS);                    // CORS permissivo

  Controllers.Users.RegisterRoutes;
  Controllers.Products.RegisterRoutes;

  THorse.Listen(9000);
end.

…e cada controller expõe um RegisterRoutes que chama THorse.Get/Post/Put/….

6. Mesmo código, sete formatos de deploy

O hello-world Console acima é o formato de deploy mais simples, mas o mesmo código THorse.Get / THorse.Listen pode ser entregue em qualquer um destes, mudando só o tipo de projeto e os Conditional Defines:

Você quer entregar como…Compile comAdicionar define HORSE_*?Hook de shutdown
Binário consoleDelphi ou FPC(nenhum) — o que você acabou de construirSetConsoleCtrlHandler (Win) / signal SIGTERM (Linux)
App VCL desktop embutindo um servidorDelphi(nenhum — escreva um projeto Forms)FormClose
Daemon LinuxDelphi ou FPC, target Linux64(nenhum — binário console + systemd)signal SIGTERM / fpSignal SIGTERM
Serviço WindowsDelphi (Service Application)(nenhum — escreva um projeto TService)TService.OnStop
App Lazarus LCL desktopFPC(nenhum — escreva um projeto Lazarus)FormClose
Módulo ApacheDelphiHORSE_APACHE(Apache é dono do ciclo de vida)
Extensão ISAPI IISDelphiHORSE_ISAPI(IIS é dono do ciclo de vida)
Binário CGI / FastCGIDelphi ou FPCHORSE_CGI / HORSE_FCGI(host é dono do ciclo de vida)

Para o caminho de alta performance, adicione um dos seguintes defines de Provider (onde a tabela diz "nenhum") pra trocar o transporte do Indy / fphttpserver padrão por um Provider assíncrono:

Define do ProviderBacked byQuando escolher
HORSE_PROVIDER_CROSSSOCKETwinddriver/Delphi-Cross-Socket (upstream) + cnpack/cnvcl para as units CnPack/Crypto — IOCP / epoll / kqueue. Instale ambos manualmente (espelhando o setup do mORMot2). Para mTLS no servidor (SSLVerifyPeer = True), use a alternativa suportada freitasjca/Delphi-Cross-Socket v1.0.3 que embute o CnPack e adiciona SetCACertificateFile + SetVerifyPeer num clone único.Você prefere controle async nativo ou já depende de Delphi-Cross-Socket. Exige Delphi 10.2+.
HORSE_PROVIDER_MORMOTmORMot2 THttpServer — IOCP / epollVocê quer compatibilidade com Delphi 7+, HTTP em modo kernel via http.sys, ou HTTP em pure-Pascal sem deps em C compilado.

Os dois Providers são mutuamente exclusivos (um transporte por build). O alias legado HORSE_CROSSSOCKET continua funcionando para sempre (PATCH-HORSE-2 traduz para HORSE_PROVIDER_CROSSSOCKET); não há alias legado para o mORMot — ele é novo.

Receitas concretas (tipo de projeto, esqueleto de código, comandos de instalação) pra cada formato: Cheatsheet de Deploy, ou a forma mais longa em Providers e Tipos de aplicação §8.

7. Inicialização Estruturada (UseStartup)

Para projetos corporativos maiores, o Horse suporta o padrão de inicialização estruturada (semelhante ao Startup do ASP.NET Core). Isso permite isolar a configuração de middlewares, ganchos e rotas em uma classe dedicada que implementa a interface IHorseStartup:

type
  THorseStartup = class(TInterfacedObject, IHorseStartup)
  public
    procedure Configure(const AInstance: THorseInstance);
  end;

procedure THorseStartup.Configure(const AInstance: THorseInstance);
begin
  // Configuração local da instância
  AInstance.Use(Jhonson);
  AInstance.Get('/ping',
    procedure(Req: THorseRequest; Res: THorseResponse)
    begin
      Res.Send('pong');
    end);
end;

Para injetar essa configuração no servidor, basta invocar o método UseStartup:

var
  LStartup: IHorseStartup;
begin
  LStartup := THorseStartup.Create;
  THorse.UseStartup(LStartup).Listen(9000);
end.

Um projeto de exemplo executável e completo está disponível em samples/delphi/console_use_startup/ConsoleUseStartup.dpr.

8. Próximos passos

  • Roteamento — declarar endpoints, parâmetros de caminho, grupos de rotas.
  • Request e Response — ler entrada, escrever saída.
  • Middleware — parsing JSON, CORS, JWT, logging.
  • Providers e Tipos de aplicação — quando trocar o transporte padrão Indy (por exemplo, para um deploy Linux de alta concorrência — veja a seção sobre CrossSocket).
  • Cheatsheet de Deploy — uma página pra entregar o binário em qualquer um dos sete formatos acima.

Resolução de problemas

SintomaCausa provável
Unit not found HorseO boss install horse não rodou — execute novamente no diretório do projeto.
Servidor inicia e sai imediatamenteA chamada Listen é não-bloqueante em algumas plataformas; em uma app console garanta que a thread principal não chegue ao end. Use um ReadLn ou um handler de sinal.
Porta já em usoOutro serviço está em :9000. Escolha outra porta ou pare o conflito.
Address already in use após um crashO processo anterior não liberou o socket. Aguarde 30 s pelo TIME_WAIT ou mude a porta.
Compilação falha no FPC com "method-pointer expected"Faltou o @ antes do nome do procedimento em THorse.Get(...).