{"id":2239,"date":"2026-02-17T10:03:56","date_gmt":"2026-02-17T08:03:56","guid":{"rendered":"https:\/\/lightrest.codeline.fr\/?page_id=2239"},"modified":"2026-03-16T19:22:01","modified_gmt":"2026-03-16T17:22:01","slug":"les-hooks","status":"publish","type":"page","link":"https:\/\/lightrest.codeline.fr\/index.php\/lightrest-composant-rest-windev\/lightrest-documentation\/les-hooks\/","title":{"rendered":"Les HOOKS"},"content":{"rendered":"\n<p>Les&nbsp;<strong>HOOKS<\/strong>&nbsp;(ou&nbsp;<em>intercepteurs d&rsquo;\u00e9v\u00e8nements<\/em>) permettent d\u2019ex\u00e9cuter du code automatiquement \u00e0 des moments cl\u00e9s du cycle de vie d\u2019une requ\u00eate LightREST.<\/p>\n\n\n\n<p>Ils servent \u00e0 g\u00e9rer proprement tous les traitements&nbsp;<strong>transverses<\/strong>&nbsp;(non m\u00e9tier), sans polluer le code des routes : s\u00e9curit\u00e9, logs, m\u00e9triques, tra\u00e7age, normalisation des r\u00e9ponses, gestion centralis\u00e9e des erreurs, etc.<\/p>\n\n\n\n<p>Un handler de Hook re\u00e7oit en param\u00e8tre une structure <a href=\"\/index.php\/la-classe-lrhook?h=EventInfo\" data-type=\"link\" data-id=\"\/index.php\/la-classe-lr-hook?h=EventInfo\"><u>EventInfo<\/u> <\/a>qui contient :<br> &#8211; Le type de l&rsquo;\u00e9v\u00e8nement intercept\u00e9<br> &#8211; l&rsquo;objet <a href=\"https:\/\/lightrest.codeline.fr\/index.php\/la-classe-lrrequest\/\" data-type=\"page\" data-id=\"2277\"><u>lrRequest<\/u> <\/a>de la requ\u00eate en cours (dont il peut renseigner le membre <a href=\"\/index.php\/la-classe-lrrequest?h=customdata\" data-type=\"page\" data-id=\"2277\"><u>CustomData<\/u> <\/a>\u00e0 l&rsquo;attention de handlers qui seront ex\u00e9cut\u00e9s ult\u00e9rieurement)<br> &#8211; l&rsquo;objet <a href=\"https:\/\/lightrest.codeline.fr\/index.php\/la-classe-lrresponse\/\" data-type=\"page\" data-id=\"2282\"><u>lrResponse<\/u> <\/a>(\u00e0 compl\u00e9ter \u00e9ventuellement)<br> &#8211; un \u00e9ventuel message (pour les \u00e9v\u00e9nements EVE_INFO, EVE_WARNING, EVE_ERROR et EVE_PANIC)<br> &#8211; le Tag de la route en cours d&rsquo;ex\u00e9cution<br><br>Un handler de Hook renvoie une valeur de type <u><a href=\"\/index.php\/la-classe-lrhook?h=Return\">EventReturn<\/a><\/u> :<br> &#8211; EVE_OK : le traitement de la route continue normalement<br> &#8211; EVE_ABORT : le traitement est interrompu. Le contenu de la r\u00e9ponse (headers+body) est envoy\u00e9 au client (avec une probable erreur HTTP)<br> &#8211; EVE_REPLACE : utilis\u00e9 pour un \u00e9v\u00e9nement EVE_BEFORE_HANDLER il permet de court-circuiter l&rsquo;ex\u00e9cution du handler par d\u00e9faut de la route en cours<\/p>\n\n\n\n<p>Le projet WinDev LightRestHooksDemo (pr\u00e9sent dans la distribution \u00e0 partir de la v3.2) illustre les fondamentaux des Hooks.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading has-large-font-size\" id=\"interet\">Int\u00e9r\u00eat<\/h2>\n\n\n\n<p>Un hook est une fonction appel\u00e9e par LightREST \u00e0 un instant pr\u00e9cis du traitement d\u2019une requ\u00eate.<\/p>\n\n\n\n<p>Il permet notamment de :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ex\u00e9cuter un&nbsp;<strong>traitement alternatif<\/strong>&nbsp;qui remplacera celui de la ROUTE appel\u00e9e<\/li>\n\n\n\n<li><strong>Filter<\/strong>&nbsp;\/&nbsp;<strong>compl\u00e9ter<\/strong>&nbsp;\/&nbsp;<strong>remplacer<\/strong>&nbsp;\/&nbsp;<strong>modifier<\/strong>&nbsp;le contenu d&rsquo;une r\u00e9ponse REST<\/li>\n\n\n\n<li><strong>Bloquer<\/strong> l&rsquo;utilisation d&rsquo;une API si certains crit\u00e8res ne sont pas remplis (ex: g\u00e9ographiques), ou interdire l&rsquo;ex\u00e9cution d&rsquo;une ROUTE (droits)<\/li>\n\n\n\n<li><strong>Injecter des donn\u00e9es<\/strong>&nbsp;dans l&rsquo;objet lrRequest re\u00e7u par un handler REST (membre CustomData)<\/li>\n\n\n\n<li>Centraliser la&nbsp;<strong>journalisation<\/strong>&nbsp;(logs structur\u00e9s, dur\u00e9e, statut HTTP\u2026)<\/li>\n\n\n\n<li>Impl\u00e9menter l\u2019<strong>authentification \/ autorisation<\/strong>&nbsp;de mani\u00e8re uniforme<\/li>\n\n\n\n<li>Ajouter du&nbsp;<strong>tra\u00e7age<\/strong>&nbsp;(Correlation ID, audit, conformit\u00e9)<\/li>\n\n\n\n<li>Collecter des&nbsp;<strong>m\u00e9triques de performance<\/strong><\/li>\n\n\n\n<li>Appliquer des r\u00e8gles globales (CORS, headers de s\u00e9curit\u00e9, cache-control\u2026)<\/li>\n\n\n\n<li>Normaliser les&nbsp;<strong>r\u00e9ponses<\/strong>&nbsp;et les&nbsp;<strong>erreurs<\/strong><\/li>\n\n\n\n<li><strong>\u00c9viter la duplication<\/strong>&nbsp;de code dans chaque route<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" id=\"avantages-cles\">Avantages cl\u00e9s<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Coh\u00e9rence<\/strong>&nbsp;: m\u00eames r\u00e8gles appliqu\u00e9es partout<\/li>\n\n\n\n<li><strong>Lisibilit\u00e9<\/strong>&nbsp;: les routes restent focalis\u00e9es sur le m\u00e9tier<\/li>\n\n\n\n<li><strong>Maintenance<\/strong>&nbsp;: un changement transverse se fait en un seul endroit<\/li>\n\n\n\n<li><strong>Robustesse<\/strong>&nbsp;: moins d\u2019oublis, moins de divergences de comportement<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading has-large-font-size\" id=\"cycle-de-vie-dune-requete-et-position-des-hooks\">Cycle de vie d\u2019une requ\u00eate et position des hooks<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"1276\" src=\"https:\/\/lightrest.codeline.fr\/wp-content\/uploads\/2026\/02\/lightrest_request_flow_v8.png\" alt=\"\" class=\"wp-image-2454\" style=\"width:951px;height:auto\" srcset=\"https:\/\/lightrest.codeline.fr\/wp-content\/uploads\/2026\/02\/lightrest_request_flow_v8.png 900w, https:\/\/lightrest.codeline.fr\/wp-content\/uploads\/2026\/02\/lightrest_request_flow_v8-212x300.png 212w, https:\/\/lightrest.codeline.fr\/wp-content\/uploads\/2026\/02\/lightrest_request_flow_v8-722x1024.png 722w, https:\/\/lightrest.codeline.fr\/wp-content\/uploads\/2026\/02\/lightrest_request_flow_v8-768x1089.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/figure>\n\n\n\n<p>Le traitement typique d\u2019une requ\u00eate REST suit ce sch\u00e9ma :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Ouverture d&rsquo;une connexion (EVE_CONNECT)<\/li>\n\n\n\n<li>R\u00e9ception de la requ\u00eate REST (EVE_RECEIVED)<\/li>\n\n\n\n<li>Ex\u00e9cution du hook&nbsp;<em>avant handler<\/em> (EVE_BEFORE_HANDLER)<\/li>\n\n\n\n<li>Ex\u00e9cution du handler de route<\/li>\n\n\n\n<li>Ex\u00e9cution du hook&nbsp;<em>apr\u00e8s handler<\/em> (EVE_BEFORE_HANDLER)<\/li>\n\n\n\n<li>Ajout des \u00e9ventuels headers automatiques (niveau serveur et route)<\/li>\n\n\n\n<li>Ex\u00e9cution du hook&nbsp;<em>avant envoi de la r\u00e9ponse<\/em> (EVE_RESULT)<\/li>\n\n\n\n<li>Envoi du r\u00e9sultat au client REST<\/li>\n<\/ol>\n\n\n\n<p>En cas d\u2019erreur (erreur applicative, panic, timeout\u2026), des hooks sp\u00e9cifiques peuvent \u00eatre ex\u00e9cut\u00e9s afin de produire une r\u00e9ponse coh\u00e9rente et effectuer les nettoyages n\u00e9cessaires.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u26a0\ufe0f Certains hooks peuvent \u00eatre ex\u00e9cut\u00e9s m\u00eame si le client a d\u00e9j\u00e0 coup\u00e9 la connexion (timeout d\u2019\u00e9criture, socket ferm\u00e9).<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading has-large-font-size\" id=\"usage-general\">Principe<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un ou plusieurs hooks sont&nbsp;<strong>enregistr\u00e9s<\/strong>&nbsp;sur le serveur ou sur une route.<\/li>\n\n\n\n<li>Chaque hook est associ\u00e9 \u00e0 une&nbsp;<strong>phase d\u2019ex\u00e9cution<\/strong> (EVE_CONNECT, EVE_BEFORE_HANDLER, EVE_ERROR, &#8230;) .<\/li>\n\n\n\n<li>Un hook re\u00e7oit le&nbsp;<strong>contexte de requ\u00eate<\/strong>&nbsp;et peut :\n<ul class=\"wp-block-list\">\n<li>Lire ou modifier la requ\u00eate et la r\u00e9ponse<\/li>\n\n\n\n<li>Ajouter des informations contextuelles<\/li>\n\n\n\n<li>Stopper le traitement<\/li>\n\n\n\n<li>D\u00e9clencher une erreur contr\u00f4l\u00e9e<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading has-large-font-size\" id=\"regles-importantes\">R\u00e8gles importantes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un hook doit \u00eatre&nbsp;<strong>rapide<\/strong>&nbsp;(\u00e9viter toute I\/O bloquante).<\/li>\n\n\n\n<li>Il doit \u00eatre&nbsp;<strong>s\u00fbr en concurrence<\/strong>&nbsp;(aucun \u00e9tat global mutable non prot\u00e9g\u00e9).<\/li>\n\n\n\n<li>Il ne doit jamais exposer de&nbsp;<strong>donn\u00e9es sensibles<\/strong>&nbsp;dans les logs.<\/li>\n\n\n\n<li>Les d\u00e9cisions globales (auth, CORS, headers communs) doivent \u00eatre trait\u00e9es ici, pas dans les routes.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading has-large-font-size\" id=\"phases-constantes-du-mecanisme-de-hooks\">Ev\u00e9nements du m\u00e9canisme de hooks<\/h2>\n\n\n\n<p>Les Hooks peuvent \u00eatre d\u00e9clar\u00e9s niveau Serveur et\/ou Route selon leur type. Un m\u00eame \u00e9v\u00e9nement \u00ab\u00a0Hook\u00e9\u00a0\u00bb sur les 2 niveaux sera d&rsquo;abord ex\u00e9cut\u00e9 sur l&rsquo;objet Serveur et ensuite sur l&rsquo;objet Route.<br><br>Plusieurs \u00e9v\u00e9nements peuvent \u00eatre attach\u00e9s \u00e0 un m\u00eame Hook (par exemple un m\u00eame handler pourra g\u00e9rer EVE_ERROR, EVE_WARNING et EVE_PANIC).<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><\/p>\n<\/blockquote>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_INFO<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Information sur l&rsquo;ex\u00e9cution<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_STARTING<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>En cours de d\u00e9marrage<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_STARTED<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>D\u00e9marr\u00e9<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_STOPPING<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>En cours d&rsquo;arr\u00eat<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_STOPPED<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Arr\u00eat\u00e9<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_CONNECT<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Nouvelle connexion<\/strong>&nbsp;(permet par exemple de filtrer les connexions par adresse IP)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_RECEIVED<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur et route.&nbsp;<strong>R\u00e9ception d&rsquo;une requ\u00eate REST<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_AUTH_FAILED<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur et route.&nbsp;<strong>Authentification \u00e9chou\u00e9e<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_BEFORE_HANDLER<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur et route.&nbsp;<strong>Avant ex\u00e9cution de la route<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_AFTER_HANDLER<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur et route.&nbsp;<strong>Apr\u00e8s ex\u00e9cution de la route<\/strong><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_RESULT<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur et route.&nbsp;<strong>Avant envoi du r\u00e9sultat<\/strong>&nbsp;(\u00e9tape ultime pour v\u00e9rifier, compl\u00e9ter, chiffrer, signer, filtrer, limiter, journaliser, &#8230;) la r\u00e9ponse avant envoi au client.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_ERROR<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Erreur<\/strong>&nbsp;lors de l&rsquo;ex\u00e9cution<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_WARNING<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Warning<\/strong>&nbsp;lors de l&rsquo;ex\u00e9cution<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>EVE_PANIC<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Hook serveur.&nbsp;<strong>Erreur grave<\/strong>&nbsp;lors de l&rsquo;ex\u00e9cution<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p>Exemple<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Authentification centralis\u00e9e via un hook serveur<\/li>\n\n\n\n<li>V\u00e9rification d\u2019un token dans le header&nbsp;<em>Authorization<\/em><\/li>\n\n\n\n<li>Retour&nbsp;<strong>401 Unauthorized<\/strong>&nbsp;avec une r\u00e9ponse JSON standardis\u00e9e<\/li>\n\n\n\n<li>Aucune route n\u2019a besoin de g\u00e9rer l\u2019authentification<\/li>\n<\/ul>\n\n\n\n<pre id=\"__code_0\" class=\"wp-block-code has-background-color has-foreground-background-color has-text-color has-background has-link-color wp-elements-4be56c84169ac033b09e1f3d72fcabdf\"><code>\/\/ =======================================================\n\/\/ Hook \u00e9v\u00e9nementiel : gestion de l\u2019authentification \n\/\/ =======================================================\nPROC\u00c9DURE ServerEventHook(stInfo lrHook.lrEventInfo) : lrHook.lrEventReturn\n\n    SI stInfo.Request.GetHeaderValue(\"ID\")=\"\" ALORS\n\n      stInfo.Response:Status      = lrResponse::StatusUnauthorized\n      stInfo.Response:ContentType = lrResponse::ContentTXT\n      stInfo.Response:Body        = \"Token ID manquant\"\n\n      \/\/ Stoppe le pipeline : la route ne sera pas ex\u00e9cut\u00e9e\n      RENVOYER lrHook::EVE_ABORT\n   FIN\n\n   RENVOYER lrHook::EVE_OK\nFIN\n<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Les&nbsp;HOOKS&nbsp;(ou&nbsp;intercepteurs d&rsquo;\u00e9v\u00e8nements) permettent d\u2019ex\u00e9cuter du code automatiquement \u00e0 des moments cl\u00e9s du cycle de vie d\u2019une requ\u00eate LightREST. Ils servent \u00e0 g\u00e9rer proprement tous les traitements&nbsp;transverses&nbsp;(non m\u00e9tier), sans polluer le code des routes : s\u00e9curit\u00e9, logs, m\u00e9triques, tra\u00e7age, normalisation des r\u00e9ponses, gestion centralis\u00e9e des erreurs, etc. Un handler de Hook re\u00e7oit en param\u00e8tre une structure [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":161,"menu_order":1,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2239","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/pages\/2239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/comments?post=2239"}],"version-history":[{"count":33,"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/pages\/2239\/revisions"}],"predecessor-version":[{"id":2702,"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/pages\/2239\/revisions\/2702"}],"up":[{"embeddable":true,"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/pages\/161"}],"wp:attachment":[{"href":"https:\/\/lightrest.codeline.fr\/index.php\/wp-json\/wp\/v2\/media?parent=2239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}