Dans le monde actuel axé sur le web, les serveurs traitent un nombre impressionnant de requêtes. Il est essentiel d’analyser, de compter, d’interpréter et de réacheminer efficacement ces demandes, en particulier lorsque l’on applique les principes MVC.
Avec l’introduction des gestionnaires de requêtes HTTP sur le serveur HTTP 4D, vous pouvez déclencher une logique commerciale spécifique basée sur les requêtes reçues. Cette fonctionnalité puissante ouvre de nombreuses possibilités, comme le détaille cet article de blog.
Avec les gestionnaires de requêtes HTTP, vous pouvez définir autant de gestionnaires que nécessaire, adaptés à des modèles d’URL et à des verbes HTTP spécifiques. Cette approche offre une granularité beaucoup plus grande que les méthodes traditionnelles d’authentification et de connexion à la base de données sur le Web, ce qui vous évite d’avoir à mettre en œuvre des déclarations Case of exhaustives.
Pourquoi des gestionnaires de requêtes ?
La gestion des gestionnaires de requêtes conduit à divers scénarios tels que :
- utiliser une URL donnée comme fournisseur de ressources(par exemple, télécharger divers fichiers en appelant une URL spécifique)
- utiliser une URL donnée comme boîte de téléchargement de fichiers(par exemple, télécharger divers fichiers en appelant une URL spécifique)
- gérer la redirection sur des pages spécifiques en fonction d’un contexte commercial(par exemple, utilisateur authentifié ou non, page introuvable, privilèges accordés ou non … etc.)
- conserver les statistiques et toute information relative à une requête reçue
- gérer une authentification via oAuth 2.0
comment configurer un gestionnaire de requêtes HTTP
Les gestionnaires de requêtes HTTP doivent être configurés dans le fichier HTTPHandlers.json du dossier Project/Sources.
Ce fichier contient une collection d’objets au format JSON. Chaque objet fait référence à un gestionnaire de requêtes avec les informations suivantes :
- le modèle d’URL à traiter
- le verbe utilisé par l’URL
- la [classe singleton + fonction] où le code du gestionnaire de requête est implémenté
Exemple de fichier
Fichier HTTPHandlers.json :
[
{
"class": "GeneralHandling",
"method": "gettingStarted",
"pattern": "start",
"verbs": "get, post"
}
]
Question: Qu’est-ce que cela signifie ?
Réponse: Cela signifie que lorsqu’une requête commençant par /start/ avec un verbe GET ou POST est reçue sur le serveur, la fonction gettingStarted du singleton GeneralHandling est exécutée.
Comment implémenter le code du gestionnaire de requêtes ?
La classe singleton mentionnée ci-dessus doit être partagée.
Entrée : une instance de la nouvelle classe 4D.IncomingMessage
La demande est reçue sur le serveur sous la forme d’une instance d’objet de la nouvelle classe 4D.IncomingMessage.
Les informations suivantes sont disponibles
- l’url complète de la demande
- les parties de l’url
- le verbe de la requête
- les en-têtes de la requête
- les paramètres mis dans l’URL (s’il y en a)
- le corps de la demande (le cas échéant)
Ensuite, le gestionnaire de la demande peut utiliser toutes ces informations pour déclencher la logique commerciale appropriée.
Résultat : une instance de la classe 4D.OutgoingMessage
Si nécessaire, le gestionnaire de la demande peut renvoyer un objet de la classe 4D.OutgoingMessage, c’est-à-dire un contenu web complet prêt à être traité par un navigateur (par exemple, le contenu d’un fichier).
un exemple simple pour commencer
Avec le même fichier HTTPHandlers.json que ci-dessus :
[
{
"class": "GeneralHandling",
"method": "gettingStarted",
"pattern": "start",
"verbs": "get, post"
}
]
La requête http://127.0.0.1/start/example?param=demo&name=4D est exécutée avec un verbe GET dans un navigateur. Elle est traitée par la fonction gettingStarted() de la classe singleton GeneralHandling ci-dessous :
return $resultshared singleton Class constructor()
Function gettingStarted($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $result:=4D.OutgoingMessage.new()
var $body : Text
$body:="Called URL: "+$request.url+"\n"
$body+="The parameters are received as an object:"+"\n"+JSON Stringify($request.urlQuery; *)+"\n"
$body+="The verb is: "+$request.verb+"\n"
$body+="There are "+String($request.urlPath.length)+" url parts - Url parts are: "+$request.urlPath.join(" - ")+"\n"+"\n"
$result.setBody($body)
$result.setHeader("Content-Type"; "text/plain")
return $result
La requête est reçue sur le serveur sous la forme de $request (une instance d’objet de la nouvelle classe 4D.IncomingMessage ).
Cet objet $request contient les propriétés suivantes
- url (String) – URL de la demande
- urlQuery (Objet) – Paramètres de la demande.
- verb (Chaîne) – Verbe
- urlPath (collection de chaînes) – Parties de l’URL de la demande
Voici la réponse :
comment gérer un corps dans la demande
La nouvelle classe 4D.IncomingMessage fournit des fonctions permettant d’obtenir les en-têtes et le corps de la requête.
exemple
Exécutons un exemple simple pour télécharger un fichier sur le serveur.
Le fichier HTTPHandlers.json :
[
{
"class": "UploadFile",
"method": "uploadFile",
"regexPattern": "/putFile",
"verbs": "POST"
}
]
Notez que le modèle d’URL est donné sous forme d’expression régulière avec la propriété regexPattern.
La requête http://127.0.0.1:8044/putFile?fileName=testFile est exécutée avec un verbe POST et un contenu de fichier dans son corps.
La classe singleton UploadFile:
Function uploadFile($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $response:=4D.OutgoingMessage.new()
var $body:="Not supported file"
var $fileName; $fileType : Text
var $file : 4D.File
var $picture : Picture
var $created : Boolean
//The file name is given as parameter in the URL
$fileName:=$request.urlQuery.fileName
// The header "Content-Type" provides the format of the body
$fileType:=$request.getHeader("Content-Type")
Case of
// The body contains a pdf file
: ($fileType="application/pdf")
$file:=File("/PACKAGE/Files/"+$fileName+".pdf")
$created:=$file.create()
// The getBlob() function returns the body of the request as a Blob
$file.setContent($request.getBlob())
$body:="Upload OK - File size: "+String($file.size)
// The body contains a jpg image
: ($fileType="image/jpeg")
$file:=File("/PACKAGE/Files/"+$fileName+".jpg")
// The getPicture() function returns the body of the request as a Picture
$picture:=$request.getPicture()
WRITE PICTURE FILE($file.platformPath; $picture)
$body:="Upload OK - Image size: "+String($file.size)
End case
$response.setBody($body)
$response.setHeader("Content-Type"; "TEXT/plain")
return $response
Le nom du fichier est donné en tant que paramètre(fileName) dans l’URL. Il est reçu dans l’objet urlQuery de la requête.
Fonctions permettant d’obtenir les en-têtes et le corps de la requête
Dans l’exemple ci-dessus, notez la fonction getHeader() qui renvoie un en-tête donné de la requête. La classe 4D.IncomingMessage offre également une propriété headers (Object) contenant tous les en-têtes de la requête.
L’en-tête Content-Type fournit le format du corps reçu. Dans cet exemple, seuls les formats pdf et jpeg sont traités.
Notez les fonctions getBlob() et getPicture() sur l’objet $request. Elles fournissent le contenu du corps dans le format approprié qui correspond à l’en-tête Content-Type.
Voir la documentation pour plus de détails sur ces fonctions.
Une fonction getText() est également disponible et fournit le corps de la requête sous forme de chaîne (si elle a été envoyée sous forme de chaîne)
Si le corps de la requête a été envoyé sous la forme d’une représentation JSON valide, la fonction getJSON() fournit sa résolution avec le type correct (par exemple, Object, Collection, String, …).
gérer la redirection
Le gestionnaire de requêtes est également capable de rediriger vers une page spécifique en renvoyant une instance de la classe4D.OutgoingMessage . L’en-tête Location doit être utilisé pour indiquer la page à rediriger.
Le statut HTTP 3xx indique que le client doit prendre des mesures supplémentaires pour compléter la demande.
Exécutons ce scénario :
– L’utilisateur peut visualiser toutes les pages html du dossier WebFolder/pages une fois qu’il est authentifié. Tant que l’utilisateur n’est pas authentifié, il est redirigé vers une page d’authentification.
– Si la page demandée ne se trouve pas dans ce dossier, une page » Non trouvé » est affichée.
– Si l’utilisateur demande une page dans un sous-dossier du dossier /pages, une page Non autorisée est servie.
Le fichier HTTPHandlers.json :
[
{
"class": "PagesHandling",
"method": "handle",
"regexPattern": "/pages/"
}
]
La classe singleton PagesHandling:
shared singleton Class constructor()
Function handle($request : 4D.IncomingMessage) : 4D.OutgoingMessage
var $result:=4D.OutgoingMessage.new()
var $file : 4D.File
//The user is not authenticated
If (Session.isGuest())
$result.setHeader("Location"; "/authentication/Authentication.html")
$result.setStatus(307)
Else
//The URL is an html page in the /pages folder
If (($request.urlPath.length=2) && (Position(".html"; $request.url)#0))
$file:=File("/PACKAGE/WebFolder"+$request.url)
//The pages exists
If ($file.exists)
$result.setBody($file.getContent())
$result.setHeader("Content-Type"; "text/html")
$result.setStatus(200)
//The pages does not exist
Else
$result.setHeader("Location"; "/error/NotFound.html")
$result.setStatus(307)
End if
//The URL is NOT a an html page in the /pages folder
Else
$result.setHeader("Location"; "/error/NotAuthorized.html")
$result.setStatus(307)
End if
End if
return $result
Notez que le gestionnaire de requêtes a accès à l’objet Session qui permet une logique d’entreprise plus complexe (vérification de la présence de certains privilèges, utilisation de l’objet partagé Session.storage ).
Téléchargez l’IDH pour vous entraîner à traiter les requêtes HTTP et n’attendez plus pour entrer dans le monde en mode projet proposant des classes et d’autres fonctionnalités puissantes.