Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for WiRL Tutorial (ConsoleApp)
Luca Minuti
Luca Minuti

Posted on

     

WiRL Tutorial (ConsoleApp)

In questo tutorial vedremo il modo più semplice per sviluppare un serverWiRL. In realtà se durante l'installazione avete installato il package designtimeWiRLDesign.dproj in Delphi, alla voceFile|New|Other, avrete una nuova opzione "WiRL Server Application Wizard" che crea una scheletro per una applicazione WiRL.

WiRL Server Application Wizard

Ma qui vedremo passo passo come configurare il vostro server manualmente in modo da avere un'idea più chiara di quello che succede.

Applicazione console

Cominciamo creando un'applicazione console che può andare bene per lo sviluppo ed eventualmente può essere facilmente trasformata in un servizio Windows per l'ambiente di produzione.

Riduciamo all'osso il codice e andiamo a trasformare quello generato da Delphi in questo:

programProject1;{$APPTYPE CONSOLE}usesSystem.SysUtils;beginReadln;end.
Enter fullscreen modeExit fullscreen mode

In questo modo abbiamo un'applicazione che apre una console e termina alla pressione del tasto invio.

Creazione del server

Per prima cosa dovremo andare a creare un oggetto di tipoTWiRLServer che si occuperà di rimanere in ascolto su una specifica porta e che smisterà il traffico HTTP. Se provate ad attivare il server (tramite la proprietàActive) riceverete un errore a runtime:

Project Project1.exe raised exception class EWiRLException with message 'CreateServer: no server registered (add "WiRL.http.Server.*" unit to the project)'.

Questo perché la struttura di TWiRLServer gli permette di aprire il canale HTTP tramite diverse librerie; e non abbiamo ancora indicato quale libreria usare. In questo caso utilizzeremo i componenti Indy (già installati in Delphi). Per farlo è sufficiente aggiungere la unitWiRL.http.Server.Indy.

programProject1;{$APPTYPE CONSOLE}usesSystem.SysUtils,WiRL.http.Server.Indy,WiRL.http.Server;varLServer:TWiRLServer;beginLServer:=TWiRLServer.Create(nil);tryLServer.SetPort(8080);LServer.Active:=True;Writeln('Server running at http://localhost:'+LServer.Port.ToString+'/');Readln;finallyLServer.Free;end;end.
Enter fullscreen modeExit fullscreen mode

Configurare l'engine

Con il codice che abbiamo scritto abbiamo già un server HTTP funzionante ma qualsiasi tentativo di connessione restituirà l'errore:

Project Project1.exe raised exception class EWiRLNotFoundException with message 'Engine not found for URL [/test]'.

Questo perché non abbiamo ancora configurato l'Engine. L'engine è la parte di WiRL che si occupa di interpretare la chiamata. Al momento esistono due engine:TWiRLEngine eTWiRLFileSystemEngine. Il primo è il motore principale di WIRL che si occupa di gestire le chiamate ReST ed è quello che vedremo in questo tutorial, mentre il secondo permette di restituire file (html, js, css, ecc.). Volendo è possibile implementare degli Engine custom per esempio per gestire chiamateSOAP eGraphQL.

Ogni engine è associato ad un path quindi per usare l'engine ReST possiamo usare un codice simile a questo:

uses...WiRL.Core.Engine,...begin...LServer.AddEngine<TWiRLEngine>('rest');...
Enter fullscreen modeExit fullscreen mode

Configurare l'applicazione

A questo punto è possibile configurare i diversi moduli di WiRL, per esempio:

  • Le risorse
  • I filtri
  • I message body writer e read
  • Le librerie esterne (es.neon eJWT)

WiRL ha un concetto diapplicazione virtuale. In questo modo è possibile in un'unica applicazione fisica creare più moduli con delle configurazioni diverse. In questo caso, per semplicità useremo solo un'applicazione virtuale con la configurazione minima.

programProject1;{$APPTYPE CONSOLE}usesSystem.SysUtils,WiRL.http.Server.Indy,WiRL.http.Server,WiRL.Core.Engine;varLServer:TWiRLServer;beginLServer:=TWiRLServer.Create(nil);tryLServer.SetPort(8080);LServer.Active:=True;LServer.AddEngine<TWiRLEngine>('rest').AddApplication('app').SetResources('*');Writeln('Server running at http://localhost:'+LServer.Port.ToString+'/');Readln;finallyLServer.Free;end;end.
Enter fullscreen modeExit fullscreen mode

In questo modo andiamo a creare l'applicazioneapp, raggiungibile tramite il path omonimo, contenente tutte le risorse.

Con questo abbiamo terminato la configurazione ma mancano ancora le risorse.

La prima risorsa

WiRL è in grado di manipolare (sia in ingresso che in uscita) diversi tipi di dati, da quelli più semplici, come stringhe o interi, a oggetti complessi compresi anche i DataSet. Questi saranno le nostrerisorse ReST. Nelledemo presenti nei sorgenti si trovano numerosi esempi. Qui vedremo come restituire un semplice oggetto di tipoTPerson serializzato comeJSON.

Incominciamo a definire la classeTPerson:

TPerson=class(TObject)privateFName:string;publicpropertyName:stringreadFNamewriteFName;end;
Enter fullscreen modeExit fullscreen mode

A questo punto dobbiamo creare una classe che sia in grado di manipolare l'oggettoTPerson. In particolare proviamo a creare una semplice classe che istanzia oggetti:

TPersonResource=classpublicfunctionGetPerson(constAName:string):TPerson;end;functionTPersonResource.GetPerson(constAName:string):TPerson;beginResult:=TPerson.Create;Result.Name:=AName;end;
Enter fullscreen modeExit fullscreen mode

Quello che abbiamo visto è una normalissima classe con un metodoGetPerson che crea le nostre persone. Non ci rimane che spiegare a WiRL come usare la classeTPersonResource per rispondere alla chiamate HTTP.WiRL ci permette di fare tutto ciò decorando la classe e i metodi con degli attributi:

[Path('person')]TPersonResource=classpublic[GET][Produces(TMediaType.APPLICATION_JSON)]functionGetPerson([QueryParam('name')]constAName:string):TPerson;end;
Enter fullscreen modeExit fullscreen mode

Gli attributi (dichiarati nella unitWiRL.Core.Attributes) che abbiamo usato sono:

  • Path: Applicato ad una classe. Indica il path a cui la risorsa risponde. In pratica quando arriva una chiamata ReST con quel path WiRL istanzierà la classe e la distruggerà al termine della chiamata. Puoi essere anche applicato ad un metodo ed in quel caso indica una "sotto risorsa", il path del metodo e quello della classe verranno usati insieme per determinare l'URL della sotto risorsa.
  • GET: Applicato ad un metodo della classe. Quel metodo di istanza sarà chiamato quando il metodo HTTP corrisponde aGET (esistono anche gli attributiPOST,PUT,DELETE, ecc).
  • Produce: Applicato ad un metodo. Indica che quel metodo deve essere chiamato SOLO se il client richiede il media type indicato (headerAccept della richiesta). Esiste anche l'attributoConsumes che serve quando con la richiesta arrivano anche dei dati nel corpo del messaggio HTTP. In quel casoConsumes indica se il nostro metodo è in grado di accettare quel tipo di contenuto.
  • QueryParam: Viene usato su un parametro della richiesta. In questo caso indica che il parametro deve essere letto dallaquery string indicata nell'URL. Esistono anchePathParam,FormParam,BodyParam e molti altri.

A questo punto dobbiamo solo registrare la nostra risorsa:

TWiRLResourceRegistry.Instance.RegisterResource<TPersonResource>;
Enter fullscreen modeExit fullscreen mode

E avviando il programma possiamo puntare il browser su:

http://localhost:8080/rest/app/person?name=luca
Enter fullscreen modeExit fullscreen mode

Riceveremo il JSON corrispondente alla classeTPerson. Per capire l'URL corretto da usare possiamo attenerci a questo schema:

Url

Dove sono indicate le varie sezioni dell'URL e chi ne è responsabile:

  • TWiRLServer: imposta la porta col metodoSetPort (8080)
  • TWiRLEngine: per la prima parte dell'URL conAddEngine (rest)
  • TWiRLApplcation: tramite il metodoAddApplication (app)
  • La risorsa: tramite l'attributoPath (person)

Conclusioni

Con questo abbiamo concluso il nostro esempio, il codice completo si trova suGitHub è possibile trovare ulteriori informazioni nellaguida ufficiale e negliesempi presenti nei sorgenti.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Full Stack Developer and Architect. Mainly involved in Delphi, Java, and JavaScript. I'm a Sencha MVP and speaker at technical conferences.
  • Location
    Italy
  • Joined

More fromLuca Minuti

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp