Les appels POST sur les API mappées (RESTMappedObject) n'exécutent pas le hook initCreate

Bonjour,

Version=4.0.P25
BuiltOn=2021-06-22 18:31 (revision 2f12327fd6f2e0e735a1c1fa852147d8f6006fa8)

Il semble que le hook initCreate ne soit plus exécuté dans le cadre des appels POST sur les API mappées. La création est néanmoins réalisée (mais il manque l’application des règles définies dans l’initCreate).

Dans le cadre d’une création va la UI, le hook est bien exécuté.

Les hooks initXxx ne sont pas appelés lors des appels d’APIs de type “écriture” (POST/PUT/DELETE = create/update/delete)

Il le sont lors des appels API de type “lecture” (GET = search/getForCreate/getForUpdate/getForDelete)

NB: La UI, dans le cadre d’une “creation” fait les deux appels API = un getForCreate pour l’affichage du formulaire de création, puis un create lors du clic sur “Save”

aïe… OK merci pour ton retour rapide.

Je n’avais pas d’historique disponible pour savoir si ils étaient appelés ou pas par le passé. Du coup ma formulation était inexacte (ce n’était pas “n’appellent plus” mais plutôt “n’appellent pas”). Le problème a été de fait révélé par le retrait d’une ligne de code en doublon où on appliquait la même règle dans le initCreate et dans le preValidate (elle a été retirée du preValidate sans vérifier si elle était bien appliquée en amont par l’initCreate).

Du coup j’ai un soucis d’application des règles de mon modèle lors de la création par API.

Si je comprends bien, je devrais pouvoir surcharger le post de RESTMappedObject pour incorporer avant le super.post() l’instanciation de l’objet concerné avec un getForCreate, puis reporter dans le body du post initial les champs initialisés par le hook initCreate.

Si c’est bien ça, l’idéal (de mon point de vue) serait que le super.post fasse nativement un getForCreate afin que je n’ai pas besoin de contourner le problème en surchargeant la méthode.

Ou alors ne pas utiliser les hooks initCreate/initUpdate pour implémenter des règles de modèle qui sont applicables (aussi) dans le cadre des appels API. → Est-ce que les hooks preXXX sont aussi concernés ?

J’ai aussi bien compris que mon problème se pose pour toutes les opérations POST/PUT/DELETE (je vais faire le tour de tous les usecases intégrés via nos API pour voir quels sont les scénarios métier impactés).

Les règles de gestion qu’on met dans des initXxx sont des règles de “préparation en vue de” qui ne doivent jamais se substituer à des règles de “validation”.

En effet il faut voir la préparation juste comme une “aide à la saisie” facultative. Dans tous les cas la validation doit (re)vérifier que ce qui est envoyé est bien intègre d’un point de vue métier.

En général si on se retrouve à devoir refaire dans le pre/postValidate ce qu’on a déjà fait dans initXxx, ou pire si on ne fait quelque chose qui relève de l’intégrité métier uniquement dans un initXxx, c’est en général révélateur d’une grave erreur de conception.

Bonjour David,

c’est bien ce qui est fait (aide à la saisie avec pré-documentation de certaines valeurs de champ).
Hors, la pré-documentation n’est pas appliquée dans le cadre de l’appel API comme le le pensais initialement.

Je pensais simplement que les règles d’aide à la saisie pouvaient s’appliquer sans discernement du point de service utilisé (UI / API).

Je peux néanmoins revoir ma logique pour post-documenter le champ dans le preValidate si l’auteur de l’appel n’a pas valorisé le champ concerné dans le body mais comme ce qui est fait dans l’initCreate sert à aider l’humain métier dès l’ouverture du formulaire de création, la règle restera en doublon de ce qui sera ré-écrit pour post-documenter dans le preValidate pour aider de manière similaire l’humain codant l’appel de l’API. Accessoirement, ça me permet de ne pas diffuser cette règle d’init du champ dans les SI amont.

Est-il envisageable d’aligner ce comportement entre la création via la UI et la création via API ou dois-je considérer le flux API spécifiquement ?

Si une règle d’aide à la saisie est appelée en “préparation UI” (= dans un initXxx) mais que cette règle doit aussi s’appliquer hors contexte UI (typiquement sur une intégration via API ou import I/O) il faut :

  • Soit l’isoler dans une méthode à part et l’appeler à la fois dans le initXxx et et dans le preValidate (sous un if ... ad hoc - ex: sur l’instance et/ou la valeur de l’attribut - pour ne pas écraser une éventuelle saisie manuelle UI)
  • Soit reproduire la logique UI dans les appels d’API => appeler un GET pour “préparer” le record puis appeler le POST/PUT/DELETE pour l’enregistrer

ok, c’est clair pour moi (j’épingle le post pour garder la trace des bonnes pratiques).
Je garde en tête qu’on est toujours mieux servi par la UI/Simplicité que par les intermédiaires :wink:

Je vais voir ce qui est le mieux de mon côté (mimer la UI dans le cadre des appels API me semble le plus logique et de fait factorisé (si je surcharge le post de RESTMappedObject dont héritent déjà toutes nos API mappées) mais ça ne résoudra pas le problème si l’on passe pas les autres endpoints comme IO par exemple).

Vous avez sous le code une map globale permettant de savoir quels hooks sont appelés dans quels contextes ?

Non il n’y a pas une “map” synthétique mais cette doc Simplicité® documentation/01-core/businessobject-code-hooks explique quelle est la vocation des différents hooks et dans quels cas ils sont appelés.

Ce qu’on conseille en formation c’est de mettre des traces dans les hooks pour bien se familiariser avec les cas où ils ont appelés.

La confusion entre le rôle des initXxx et celui des pre/postValidate est classique, on en parle en formation mais tant qu’on n’y a pas été confronté dans la vraie vie ça reste conceptuel…

Une règle qui doit s’appliquer dans tous les cas d’enregistrement (UI, API, I/O) doit être impérativement implémentée dans le pre/postValidate ou preSave/Create/Update, parfois il peut être intéressant de “préjouer” tout ou partie des règles au titre de la préparation (donc dans un initXxx) pour aider l’utilisateur UI mais en aucun cas le fait d’implémenter une règle à ce niveau ne doit être considéré comme fiable d’un point de vue intégrité métier.

Sans parler des cas d’appels API ou d’import I/O, dans la UI un user affiche un formulaire, via la console du navigateur il change les valeurs préparées par le initXxx - il peut le faire y compris sur des attributs read only - et enregistre => si la validation ne revérifie pas les choses importantes les règles métier de préparation peuvent être contournées très facilement.

C’est pour ça que j’ai coutume de dire que ce qui s’implémente dans un initXxx n’a, par construction, strictement aucune valeur métier (à peine plus qu’une règle implémentée coté client en JS dans les pages), c’est uniquement de l’aide à la saisie

1 Like

Merci beaucoup pour ce refresh… en effet, depuis ma formation en 2017, j’ai largement eu le temps de “corrompre” ce dont j’ai pu me souvenir… le passage en revue de tous les initXXX sera l’occasion de remettre les éventuelles règles “hors la loi” dans le droit chemin.

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.