Section courante

A propos

Section administrative du site

 Langage  Elément  Tutoriel  Aide 
ABAP/4
Ada
Assembleur
Assembly & bytecode
ASP (Active Server Pages)
Basic
C
C++
C# (C Sharp)
Cobol
ColdFusion
Fortran
HTML
Java
JavaScript
LISP
Logo
LotusScript
Oberon
Pascal
Perl
PHP
PL/1
Prolog
Python
Rebol
REXX
Ruby
Rust
SAS
NoSQL
SQL
Swift
X++ (Axapta)
GNAT
SMALLAda
VHDL
Assembleur 370
Assembleur 1802
Assembleur 4004
Assembleur 6502
Assembleur 6800
Assembleur 68000
Assembleur 8080 et 8085
Assembleur 8089
Assembleur 80x86
Assembleur AGC4
Assembleur ARM
Assembleur DPS 8000
Assembleur i860
Assembleur Itanium
Assembleur MIPS
Assembleur PDP-11
Assembleur PowerPC
Assembleur RISC-V
Assembleur SPARC
Assembleur SuperH
Assembleur UNIVAC I
Assembleur VAX
Assembleur Z80
Assembleur Z8000
Assembleur z/Architecture
ASSEMBLER/MONITOR 64
Micol Assembler
GFA Assembler
A86
MASM (Macro Assembler)
TASM (Turbo Assembler)
CIL
Jasmin
LLVM
MSIL
Parrot
P-Code (PCode)
SWEET16
G-Pascal
ASP 1.0
ASP 2.0
ASP 3.0
ASP.NET
ASP.NET Core
ABasiC (Amiga)
Adam SmartBASIC
Altair BASIC
AmigaBASIC (Amiga)
AMOS Basic (Amiga)
Atari Basic (Atari 400, 600 XL, 800, 800XL)
Basic Apple II (Integer BASIC/APPLESOFT)
Basic Commodore 64 (CBM-BASIC)
Basic Commodore 128 (BASIC 7.0)
Basic Commodore VIC-20 (CBM-BASIC 2.0)
Basic Coco 1 (Color Basic)
Basic Coco 2 (Extended Color Basic)
Basic Coco 3 (Extended Color Basic 2.0)
BASICA (PC DOS)
Basic Pro
BBC BASIC
Blitz BASIC (Amiga)
DarkBASIC
Dartmouth BASIC
GFA-Basic (Atari ST/Amiga)
GWBASIC (MS-DOS)
Liberty BASIC
Locomotive BASIC (Amstrad CPC)
MSX-Basic
Omikron Basic (Atari ST)
Oric Extended Basic
Power Basic
Quick Basic/QBasic (MS-DOS)
Sinclair BASIC (ZX80, ZX81, ZX Spectrum)
ST BASIC (Atari ST)
Turbo Basic
Vintage BASIC
VBScript
Visual Basic (VB)
Visual Basic .NET (VB .NET)
Visual Basic pour DOS
Yabasic
BeckerBASIC
SIMONS' BASIC
Basic09 d'OS-9
Disk Extended Color Basic
Basic09 d'OS-9
Disk Extended Color Basic
Access
Excel
Visual Basic pour Windows
Visual Basic .NET pour Windows
C Shell Unix (csh)
C pour Amiga
C pour Atari ST
C pour DOS
C pour Falcon030
C pour GEMDOS (Atari ST)
C pour Linux
C pour PowerTV OS
C pour OS/2
C pour Unix
C pour Windows
Aztec C
CoCo-C
GNU C
HiSoft C
IBM C/2
Introl-C
Lattice C
Microsoft C
MinGW C
MSX-C
Open Watcom C
OS-9 C Compiler
Pure C
Quick C
Turbo C
HiSoft C for Atari ST
HiSoft C for CP/M (Amstrad CPC)
C++ pour OS/2
C++ pour Windows
Borland C++
C++Builder
IBM VisualAge C++
Intel C++
MinGW C++
Open Watcom C++
Symantec C++
Turbo C++
Visual C++
Visual C++ .NET
Watcom C++
Zortech C++
C# (C Sharp) pour Windows
Apple III Cobol
Microsoft Cobol
BlueDragon
Lucee
OpenBD
Railo
Smith Project
Microsoft Fortran
WATFOR-77
CSS
FBML
Open Graph
SVG
XML
XSL/XSLT
LESS
SASS
GCJ (GNU)
JSP
Jython
Visual J++
Node.js
TypeScript
AutoLISP
ACSLogo
LotusScript pour Windows
Amiga Oberon
Oberon .NET
Apple Pascal
Delphi/Kylix/Lazarus
Free Pascal
GNU Pascal
HighSpeed Pascal
IBM Personal Computer Pascal
Lisa Pascal
Maxon Pascal
MPW Pascal
OS-9 Pascal
OSS Personal Pascal
Pascal-86
Pascal du Cray Research
Pascal/VS
Pascal-XT
PURE Pascal
QuickPascal
RemObjets Chrome
Sun Pascal
THINK Pascal
Tiny Pascal (TRS-80)
Turbo Pascal
UCSD Pascal
VAX Pascal
Virtual Pascal
Turbo Pascal for CP/M-80
Turbo Pascal for DOS
Turbo Pascal for Macintosh
Turbo Pascal for Windows
CodeIgniter (Cadre d'application)
Drupal (Projet)
Joomla! (Projet)
Phalanger (PHP .NET)
phpBB (Projet)
Smarty (balise)
Twig (balise)
Symfony (Cadre d'application)
WordPress (Projet)
Zend (Cadre d'application)
PL360
PL/M-80
PL/M-86
Turbo Prolog
CPython
IronPython
Jython
PyPy
AREXX
Regina REXX
JMP
Btrieve
Cassandra
Clipper
CouchDB
dBASE
Hbase
Hypertable
MongoDB
Redis
Access
BigQuery
DB2
H2
Interbase
MySQL
Oracle
PostgreSQL
SAP HANA
SQL Server
Sybase
U-SQL
Introduction
Référence des unités
Les premiers pas
Travailler avec l'application
Conteneur de dépendances
Répartiteur
Environnement CGI
Configurer l'application
Gestionnaire d'erreurs
Travailler avec un routeur
Travailler avec une base de données
Utilisation des journaux de bord
Travailler avec Fano CLI
Préface
Notes légales
Dictionnaire
Recherche

Travailler avec un routeur

Routeur et route

Dans Fano Framework, une route est une règle d'association entre le modèle de chemin d'URL, la méthode HTTP et le code la gérant. Le routeur gère une ou plusieurs routes et fait correspondre le chemin d'URL de la demande, en extrait les données et sélectionne le code les gérant (instance de gestionnaire de demande, c'est-à-dire le contrôleur). Le routeur est toute classe implémentant l'interface IRouter.

Création d'une route pour la méthode GET

  1. Var
  2.     router:IRouter;
  3.     handler:IRequestHandler;
  4. ...
  5. router.get('/', handler);

Création d'un itinéraire pour la méthode POST

  1. router.post('/submit', handler);

Création d'un itinéraire pour la méthode PUT

  1. router.put('/submit', handler);

Création d'un itinéraire pour la méthode DELETE

  1. router.delete('/submit', handler);

Création d'un itinéraire pour la méthode PATCH

  1. router.patch('/submit', handler);

Création d'un itinéraire pour la méthode HEAD

  1. router.head('/', handler);

Création d'un itinéraire pour la méthode OPTIONS

  1. router.options('/', handler);

Créer un itinéraire pour plusieurs méthodes

  1. router.map(['GET', 'POST'], '/', handler);

Créer un itinéraire pour toutes les méthodes

  1. router.any('/', handler);

Itinéraire avec paramètres

Un itinéraire peut avoir des paramètres comme indiqué dans l'exemple suivant :

  1. router.get('/user/{username}', myUserHandler);
  2. router.get('/products/{id}/{productSlug}', productList);

Correspondance de route

Si nous avons la configuration de la route suivante :

  1. Var
  2.     router:IRouter;
  3.     myAppHandler, anotherAppHandler:IRequestHandler;
  4. ...
  5.  
  6. //Requête GET
  7. router.get('/my/app', myAppHandler);
  8.  
  9. //Requête POST
  10. router.post('/another/app', anotherAppHandler);

Si le nom d'hôte de votre application est exemple.com et que le client ouvre http://exemple.com/mon/app via un navigateur, notre application recevra la méthode GET de la requête pour les ressources /mon/app. Le routeur fera correspondre la méthode HTTP et l'URL et renverra myAppHandler en tant que code chargé de gérer cette requête.

Si le client ouvre http://exemple.com/autre/app via un navigateur, notre application recevra la méthode GET de la requête pour les ressources /autre/app. Le routeur trouvera une correspondance avec /autre/app mais comme il n'est enregistré que pour la requête POST, une exception EMethodNotAllowed sera générée avec le code d'erreur HTTP 405.

Si le client ouvre http://exemple.com/pas/existe via un navigateur, notre application recevra la méthode GET de la requête pour les ressources /pas/existe. Le routeur ne trouvera aucune correspondance. Si cela se produit, une exception ERouteHandlerNotFound sera générée avec le code d'erreur HTTP 404.

Créer des routes d'application avec le générateur de routes

Pour créer des routes d'application, vous devez créer une classe implémentant l'interface IRouteBuilder :

  1. IRouteBuilder=Interface
  2.     ['{46016416-B249-4258-B76A-7F5B55E8348D}']
  3.  
  4.     (*!----------------------------------------------
  5. * créer des routes d'application
  6. * ----------------------------------------------
  7. * @param cntr instance de conteneur de dépendances
  8. * @param rtr instance de routeur
  9. *-----------------------------------------------*)
  10.     Procedure buildRoutes(const cntr:IDependencyContainer; Const rtr:IRouter);
  11. End;

Le Fano Framework fournit une classe abstraite de base TRouteBuilder dont vous pouvez étendre et implémenter sa méthode buildRoutes() et la transmettre lors de la création d'une instance d'application comme indiqué dans le code suivant :

  1. TAppRoutes=Class(TRouteBuilder)
  2.  Public
  3.     Procedure buildRoutes(
  4.         const container : IDependencyContainer;
  5.         const router : IRouter
  6.     ); override;
  7. End;
  8. ...
  9. Procedure TAppRoutes.buildRoutes(
  10.     Const container:IDependencyContainer;
  11.     Const router:IRouter
  12. );
  13. Begin
  14.    //Inscrivez tous les itinéraires ici
  15.    router.get('/', handler);
  16. End;

Ensuite, créez son instance et transmettez-la au constructeur de l'application.

  1. appInstance:=TCgiWebApplication.create(
  2.     TAppServiceProvider.create(),
  3.     TAppRoutes.create()
  4. );

Si vous utilisez Fano CLI pour créer des applications Web, vous remarquerez peut-être que les itinéraires sont séparés en un ou plusieurs fichiers d'inclusion étant insérés dans une classe chargée de créer des itinéraires d'application, comme indiqué dans l'exemple suivant :

  1. Procedure TAppRoutes.buildRoutes(
  2.     Const container:IDependencyContainer;
  3.     Const router:IRouter
  4. );
  5. Begin
  6.     {$INCLUDE Routes/routes.inc}
  7. End;

Il s'agit simplement d'une convention utilisée par les outils CLI Fano car elle est simple à générer.

Le Fano Framework veille à ce que vous fournissiez une classe implémentant IRouteBuilder. Il ne se soucie pas de la manière dont vous l'implémentez. Vous êtes donc libre de composer la classe de création d'itinéraire comme bon vous semble.

Par exemple, vous pouvez créer une implémentation IRouteBuilder distincte pour chaque fonctionnalité pour une meilleure organisation du code, puis les composer à l'aide de la classe TCompositeRouteBuilder comme indiqué dans l'exemple ci-dessous :

  1. TUsersRoutes=Class(TRouteBuilder)
  2.  Public
  3.     Procedure buildRoutes(
  4.         Const container:IDependencyContainer;
  5.         Const router:IRouter
  6.     ); override;
  7. End;
  8. ...
  9. Procedure TUsersRoutes.buildRoutes(
  10.     Const container:IDependencyContainer;
  11.     Const router:IRouter
  12. );
  13. Begin
  14.     //Enregistrer les itinéraires associés aux utilisateurs ici
  15. End;

Pour les itinéraires de fonctionnalités de produit :

  1. TProductRoutes=Class(TRouteBuilder)
  2. public
  3.     Procedure buildRoutes(
  4.         Const container:IDependencyContainer;
  5.         Const router:IRouter
  6.     ); override;
  7. End;
  8. ...
  9. Procedure TProductRoutes.buildRoutes(
  10.     Const container:IDependencyContainer;
  11.     Const router:IRouter
  12. );
  13. Begin
  14.     //Enregistrer les produits liés aux itinéraires ici
  15. End;

Et lorsque vous créez une application, vous les composez comme suit :

  1. appInstance:=TCgiWebApplication.create(
  2.     TAppServiceProvider.create(),
  3.     TCompositeRouteBuilder.create([
  4.         TUserRoutes.create(),
  5.         TProductRoutes.create()
  6.     ]);
  7. );

Veuillez noter que TCompositeRouteBuilder est une implémentation intégrée d'IRouteBuilder composant une ou plusieurs instances d'IRouteBuilder en une seule.

Définir le nom de la route ou les intergiciels avec l'interface IRoute

Toutes les méthodes enregistrant le gestionnaire de requêtes telles que get(), post(),.., renvoient une instance de l'interface IRoute que vous pouvez utiliser pour attribuer un nom à la route ou attacher un intergiciel. Le code suivant répertorie toutes les méthodes de cette interface :

  1. Function setName(Const routeName:shortstring):IRoute;
  2. Function getName():shortstring;
  3. Function add(Const amiddleware:IMiddleware):IRoute;

Par exemple pour définir le nom de la route et attacher un middleware :

  1. var authOnlyMiddleware : IMiddleware;
  2. ...
  3. router.post('/user/submit', handler).setName('create-user').add(authOnlyMiddleware);

Obtenir le paramètre de la route

Le troisième paramètre de la méthode handleRequest() de l'interface IRequestHandler donne une instance de l'interface IRouteArgsReader pour permettre à l'application de récupérer les paramètres de la route.

Si vous avez le modèle de route /maroute/{name} et que vous accédez à la route via l'URL http://exemple.com/maroute/jean, vous pouvez obtenir la valeur du paramètre name comme suit :

  1. Function TMyController.handleRequest(
  2.     Const request:IRequest;
  3.     Const response:IResponse;
  4.     Const args:IRouteArgsReader
  5. ):IResponse;
  6. Var
  7.     arg:TPlaceholder;
  8. Begin
  9.     arg:=args.getArg('name');
  10.     //arg.name = 'name', arg.value = 'jean'
  11. End;

Si vous êtes intéressé uniquement par sa valeur, vous pouvez appeler getValue() et passer le nom de paramètre. Il renvoie la valeur sous forme de chaîne de caractères :

  1. Var name:String;
  2. ...
  3. name:=args.getValue('name'); //name = 'jean'

ou avec une syntaxe simplifiée de type tableau :

  1. name:=args['name']; //name = 'jean'

Les codes ci-dessus imprimeront une sortie identique comme suit :

  1. name:=args.getArg('name').value;

Vous pouvez obtenir tous les paramètres de route en utilisant la méthode getArgs() :

  1. Function TMyController.handleRequest(
  2.     Const request:IRequest;
  3.     Const response:IResponse;
  4.     Const args:IRouteArgsReader
  5. ):IResponse;
  6. Var placeHolders:TArrayOfPlaceholders;
  7.     arg:TPlaceholder;
  8.     i:integer;
  9. Begin
  10.     placeHolders:=args.getArgs();
  11.     For i:=0 to length(placeholders)-1 do Begin
  12.         arg:=placeholders[i];
  13.     End;
  14. End;

Créer une instance de routeur

Le Fano Framework est fourni avec une implémentation de routeur de base, la classe TRouter, implémentant l'interface IRouter :

  1. container.add('router', TSimpleRouterFactory.create());

La classe TSimpleRouterFactory crée une instance de routeur prenant en charge l'analyse des paramètres de route. Vous pouvez également utiliser la classe TRouterFactory créeant une instance de routeur ne prenant pas en charge le paramètre de route, mais étant plus rapide lors de la correspondance de l'URL de la demande :

  1. container.add('router', TRouterFactory.create());

Si vous n'avez besoin que d'un modèle de chemin d'URL statique, vous devez l'utiliser.

Si vous créez un fournisseur de services d'application hérité de TBasicAppServiceProvider, il créera un routeur par défaut à l'aide de la classe TSimpleRouterFactory étant suffisante pour la plupart des applications.

Remplacer l'instance du routeur

Si vous souhaitez remplacer le routeur par une implémentation différente, vous pouvez remplacer la méthode buildRouter() de TBasicAppServiceProvider. Par exemple :

  1. TMyAppProvider=Class(TBasicAppServiceProvider)
  2.  Private
  3.     fRouterMatcher:IRouteMatcher;
  4.  Public
  5.     Function getRouteMatcher():IRouteMatcher; override;
  6.     Function buildRouter(Const cntr:IDependencyContainer):IRouter; override;
  7. End;
  8. ...
  9. Function TMyAppProvider.buildRouter(Const cntr:IDependencyContainer):IRouter;Begin
  10.     ctnr.add('router', TRouterFactory.create());
  11.     result:=ctnr['router'] as IRouter;
  12.     fRouteMatcher:=Result as IRouteMatcher;
  13. End;
  14.  
  15. Function TMyAppProvider.getRouteMatcher():IRouteMatcher;Begin
  16.     Result:=fRouteMatcher;
  17. End;

Notez que IRouteMatcher est une interface chargée de faire correspondre l'URL de la demande et TRouter l'implémente.



PARTAGER CETTE PAGE SUR
Dernière mise à jour : Vendredi, le 18 octobre 2024