Saltar al contenido principal

Daf.Web — Servidor HTTP ligero y enrutamiento por atributos

🌍 Idioma: English | Español

Servidor HTTP y capa de controladores para aplicaciones DAFce. Construido sobre TIdHTTPWebBrokerBridge de Indy y Delphi WebBroker, añade controladores compatibles con DI, enrutamiento basado en atributos y helpers de action-result.

No enlaza ni DataSnap ni DBX: un módulo que sirve HTTP no tiene por qué meter una pila de remoting y una capa de base de datos en tu aplicación, y este no lo hace.

Delphi 12+ Licencia


Inicio rápido

uses Web.HTTPApp, Daf.Web.Controller;

type
  [WebRoutePrefix('/api/pedidos')]
  TPedidosController = class(TWebController)
    [WebRoute(mtGet, '/')]
    function Listar: IActionResult;

    [WebRoute(mtPost, '/')]
    function Crear([FromBody] Command: TCreateOrderCommand): IActionResult;
  end;

function TPedidosController.Listar: IActionResult;
begin
  Result := Ok(FOrderService.GetAll);
end;

function TPedidosController.Crear(Command: TCreateOrderCommand): IActionResult;
begin
  FMediator.Send<TCreateOrderCommand>(Command);
  Result := Created('/api/pedidos/' + IntToStr(Command.OrderId));
end;

Web.HTTPApp está por las constantes de verbo — mtGet, mtPost y las demás. Todo lo demás que necesita un controlador, atributos incluidos, sale de Daf.Web.Controller.

El router construye Command a partir del cuerpo JSON con su constructor sin parámetros, y lo libera cuando se ha ejecutado el resultado de la acción. Un cuerpo que no es un objeto JSON responde 400 Bad Request.


Arrancar el servidor

uses
  Daf.Extensions.HttpServer,   // IDafHttpServer
  Daf.HttpServer;              // TDafHttpServer

var Server: IDafHttpServer := TDafHttpServer.Create(TWebModule1, Config, LoggerFactory);
Server.Port := 8080;
Server.Start;
WriteLn('Escuchando en :8080');
ReadLn;
Server.Stop;

⚠️ Sostenlo en una IDafHttpServer. TDafHttpServer lleva contador de referencias, así que una variable del tipo de la clase deja el servidor sin dueño y se fuga.

Config['Port'] fija el puerto al construir y es obligatoria: si la clave falta, el indexador devuelve la cadena vacía y el constructor falla al convertirla. Asignar Port después, como arriba, lo sustituye. Componer por la variante de aplicación en vez de a mano siembra el puerto por ti —ver la guía—.

Con el puerto ocupado, Start dispara OnError y después lanza una excepción que nombra el puerto: Cannot start: port 8080 is in use. OnError es un TServerErrorEvent, procedure(Sender: TObject; const Error: Exception) of object, con el servidor como Sender: el manejador lee la excepción, que Start lanza a continuación, y ni la libera ni la guarda. ASP.NET Core no tiene este evento.


Helpers de respuesta

Método Status
Ok(valor) 200
Created(msg) 201
Accepted 202
NoContent 204
BadRequest(msg) 400
Unauthorized 401
Forbidden 403
NotFound 404
Conflict 409
InternalServerError(msg) 500
Html(texto) 200 text/html
Page(fichero) 200 página renderizada en servidor

El mensaje que recibe un helper de estado pasa a ser el cuerpo de la respuesta. Ninguno pone cabecera Location.


El ciclo de vida va a cambiar

El servidor se gobierna a sí mismo: Start, Stop y los eventos OnStarting / OnStarted / OnStopping / OnStopped / OnError. DAF ya tiene un modelo de ciclo de vida para lo que gobierna un host —IHostedService y AddHostedService<T>— y este servidor todavía no lo usa.

Lo usará. La forma prevista es que TDafHttpServer implemente IHostedService además, con Start y Stop pasando a ser el detalle interno en vez de la API que se maneja; los eventos son más finos que nada que exponga IHostedService, así que se quedan. Queda escrito aquí en vez de dejarlo para que lo descubra el primero que llegue: quien componga un host hoy debe contar con que esa costura se mueve.


Documentación

  • 📖 Guía de uso — atributos de enrutamiento, binding de parámetros, DI, TDafHttpServer, action results personalizados