Free Pascal

Costruire un'API REST in Free Pascal con il framework Horse

calendar_today personTeam EGSOFT schedule5 min di lettura
info

Disclaimer: le informazioni pubblicate in questa sezione hanno finalità di pura divulgazione tecnica. EG Software S.r.l. non si assume alcuna responsabilità per un utilizzo improprio dei contenuti, né per eventuali danni diretti o indiretti derivanti dalla loro applicazione, e non garantisce l'aggiornamento, l'accuratezza o la completezza delle informazioni riportate. Prima di utilizzare in produzione codice o procedure qui descritte, verificane sempre l'adeguatezza al proprio contesto.

Free Pascal non è soltanto un linguaggio per applicazioni desktop: grazie a framework come Horse — ispirato a Express.js per Node.js — è possibile scrivere un server REST completo con poche righe di codice, gestendo rotte, middleware e risposte JSON in modo dichiarativo. Horse funziona sia con Delphi sia con Free Pascal/Lazarus, appoggiandosi rispettivamente a Indy o ai binding HTTP di FPC.

Definire le rotte con THorse

La classe THorse espone metodi statici che ricalcano i verbi HTTP: Get, Post, Put, Delete. Ogni rotta riceve una procedura con la firma (Req: THorseRequest; Res: THorseResponse; Next: TNextProc), lo stesso pattern middleware/handler che si trova in molti framework web.

program ApiServer;

{$mode objfpc}{$H+}

uses
  SysUtils, Classes, fpjson, Horse;

procedure GetPersonaHandler(Req: THorseRequest; Res: THorseResponse; Next: TNextProc);
var
  Nome: string;
begin
  Nome := Req.Params['nome'];
  Res.Send('{"nome":"' + Nome + '"}').Status(200);
end;

begin
  THorse.Get('/persona/:nome', GetPersonaHandler);
  THorse.Listen(9000);
end.

Un middleware di autenticazione

Registrando più handler sulla stessa rotta, il primo può fare da guardia: se non chiama Next, la richiesta si ferma lì. È il pattern classico per un controllo di autenticazione basato su header Authorization: Bearer ....

procedure Autentica(Req: THorseRequest; Res: THorseResponse; Next: TNextProc);
var
  IntestazioneAuth, Token: string;
begin
  IntestazioneAuth := Req.Headers['Authorization'];
  if (IntestazioneAuth <> '') and (Pos('Bearer ', IntestazioneAuth) = 1) then
  begin
    Token := Copy(IntestazioneAuth, 8, Length(IntestazioneAuth));
    if VerificaToken(Token) then
    begin
      Next;
      Exit;
    end;
  end;
  Res.Send('{"result":false,"message":"Unauthorized"}').Status(401);
end;

begin
  THorse.Get('/persona', Autentica);
  THorse.Get('/persona', GetListaPersoneHandler);
  THorse.Listen(9000);
end.

Nell'esempio da cui è tratto questo pattern, il token viene generato con una firma calcolata "in casa" (hash più codifica base64url), un esercizio utile per capire la struttura di un JWT — header, payload e firma separati da un punto — ma non un'implementazione da usare così com'è in produzione: per un'API reale conviene appoggiarsi a una libreria JWT matura, con un algoritmo di firma verificato (HMAC-SHA256 vero, non un hash "fatto in casa"), e a un secret conservato in un file di configurazione, mai scritto in chiaro nel sorgente.

Serializzare le risposte con fpjson

La unit fpjson (accompagnata da jsonparser per la lettura) fornisce le classi TJSONObject e TJSONArray per costruire e leggere payload JSON senza dipendenze esterne. Un pattern comodo è centralizzare la busta di risposta in un'unica funzione:

procedure InviaRisposta(Res: THorseResponse; Status: Integer;
  Successo: Boolean; const Messaggio: string; Valore: TJSONData = nil);
var
  Risposta: TJSONObject;
begin
  Risposta := TJSONObject.Create;
  try
    Risposta.Add('result', TJSONBoolean.Create(Successo));
    Risposta.Add('message', TJSONString.Create(Messaggio));
    if Assigned(Valore) then
      Risposta.Add('value', Valore);
    Res.Send(Risposta.AsJSON).Status(Status);
  finally
    Risposta.Free;
  end;
end;

Con questi tre ingredienti — rotte, middleware e busta JSON uniforme — si ottiene rapidamente un'API coerente, testabile con qualunque client HTTP, incluso un semplice script PHP con cURL, come vedremo nel prossimo articolo.

Altri articoli su Free Pascal grid_viewTutte le tematiche
Scrivici su WhatsApp