From c1c7080788e74e63d184d3c279da6c6dff721eb4 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 1 Jun 2026 23:01:14 +0200 Subject: [PATCH] perf(commercial) : memoize request payload decoding in ClientProcessor --- .../State/Processor/ClientProcessor.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Module/Commercial/Infrastructure/ApiPlatform/State/Processor/ClientProcessor.php b/src/Module/Commercial/Infrastructure/ApiPlatform/State/Processor/ClientProcessor.php index de2017b..f0c5c90 100644 --- a/src/Module/Commercial/Infrastructure/ApiPlatform/State/Processor/ClientProcessor.php +++ b/src/Module/Commercial/Infrastructure/ApiPlatform/State/Processor/ClientProcessor.php @@ -83,6 +83,19 @@ final class ClientProcessor implements ProcessorInterface private const string PERM_ACCOUNTING_MANAGE = 'commercial.clients.accounting.manage'; private const string PERM_ARCHIVE = 'commercial.clients.archive'; + /** + * Memoisation du dernier corps de requete decode, clos par le contenu brut. + * payloadKeys() est appele plusieurs fois par requete (writablePayloadKeys, + * categoriesChanged...) : on evite de rejouer json_decode a chaque appel. La + * cle etant le contenu lui-meme et le calcul une fonction pure de ce contenu, + * aucune fuite n'est possible entre requetes sur ce service partage (un meme + * corps redonne les memes cles). + */ + private ?string $decodedContent = null; + + /** @var list Cles de premier niveau correspondant au corps memoise. */ + private array $decodedPayloadKeys = []; + public function __construct( #[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')] private readonly ProcessorInterface $persistProcessor, @@ -576,6 +589,26 @@ final class ClientProcessor implements ProcessorInterface } $content = $request->getContent(); + + // Cache hit : meme corps brut que le dernier decodage -> memes cles. + if ($content === $this->decodedContent) { + return $this->decodedPayloadKeys; + } + + $this->decodedContent = $content; + $this->decodedPayloadKeys = $this->extractPayloadKeys($content); + + return $this->decodedPayloadKeys; + } + + /** + * Decode le corps brut et en extrait les cles de premier niveau (chaines). + * Corps vide ou JSON invalide -> aucune cle. + * + * @return list + */ + private function extractPayloadKeys(string $content): array + { if ('' === $content) { return []; }